diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..39d86671 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto eol=lf +*.sln text eol=crlf +*.vcxproj text eol=crlf +*.vcxproj.filters text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..16ef7f95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,67 @@ +.deps +.libs +autom4te.cache +m4 + +ac_cfg.h +ac_cfg.h.in +aclocal.m4 +avrdude +avrdude.conf +avrdude.conf.tmp +avrdude.spec +compile +config.guess +config.log +config.status +config.sub +config_gram.c +config_gram.h +configure +depcomp +INSTALL +install-sh +lexer.c +libtool +ltmain.sh +Makefile +Makefile.in +mdate-sh +mkinstalldirs +missing +stamp-h.in +stamp-h1 +texinfo.tex +y.output +y.tab.h +ylwrap + +*.o +*.lo +*.a +*.la +*.diff +*.patch + +## Ignore Visual Studio build results + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +x86/ + +# Visual Studio cache/options directory +.vs/ + +# Include pre-built files +!ac_cfg.h +!config_gram.c +!config_gram.h +!lexer.c diff --git a/avrdude.h b/avrdude.h index 738578f1..fea219ed 100644 --- a/avrdude.h +++ b/avrdude.h @@ -42,6 +42,10 @@ int avrdude_message(const int msglvl, const char *format, ...); #include "ac_cfg.h" #include +#ifdef _MSC_VER +#include "msvc/msvc_compat.h" +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/avrdude.sln b/avrdude.sln new file mode 100644 index 00000000..ff19192b --- /dev/null +++ b/avrdude.sln @@ -0,0 +1,61 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30104.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avrdude", "avrdude.vcxproj", "{718DDC4C-324E-485F-BE18-2D211659A2F4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libelf", "external\libelf\libelf.vcxproj", "{A2D07885-A0D1-473B-83B2-209CD008EE8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhidapi", "external\libhidapi\libhidapi.vcxproj", "{17054837-6AE6-44D7-914D-9625EDEF4657}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb", "external\libusb\libusb.vcxproj", "{22615EC5-9DBC-4538-9C01-2CD535B3810B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Debug|x64.ActiveCfg = Debug|x64 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Debug|x64.Build.0 = Debug|x64 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Debug|x86.ActiveCfg = Debug|Win32 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Debug|x86.Build.0 = Debug|Win32 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Release|x64.ActiveCfg = Release|x64 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Release|x64.Build.0 = Release|x64 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Release|x86.ActiveCfg = Release|Win32 + {718DDC4C-324E-485F-BE18-2D211659A2F4}.Release|x86.Build.0 = Release|Win32 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Debug|x64.ActiveCfg = Debug|x64 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Debug|x64.Build.0 = Debug|x64 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Debug|x86.ActiveCfg = Debug|Win32 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Debug|x86.Build.0 = Debug|Win32 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Release|x64.ActiveCfg = Release|x64 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Release|x64.Build.0 = Release|x64 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Release|x86.ActiveCfg = Release|Win32 + {A2D07885-A0D1-473B-83B2-209CD008EE8F}.Release|x86.Build.0 = Release|Win32 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Debug|x64.ActiveCfg = Debug|x64 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Debug|x64.Build.0 = Debug|x64 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Debug|x86.ActiveCfg = Debug|Win32 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Debug|x86.Build.0 = Debug|Win32 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Release|x64.ActiveCfg = Release|x64 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Release|x64.Build.0 = Release|x64 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Release|x86.ActiveCfg = Release|Win32 + {17054837-6AE6-44D7-914D-9625EDEF4657}.Release|x86.Build.0 = Release|Win32 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Debug|x64.ActiveCfg = Debug|x64 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Debug|x64.Build.0 = Debug|x64 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Debug|x86.ActiveCfg = Debug|Win32 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Debug|x86.Build.0 = Debug|Win32 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x64.ActiveCfg = Release|x64 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x64.Build.0 = Release|x64 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x86.ActiveCfg = Release|Win32 + {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6126B4FE-5EEC-46A7-934A-F3B0314F6B75} + EndGlobalSection +EndGlobal diff --git a/avrdude.vcxproj b/avrdude.vcxproj new file mode 100644 index 00000000..dde4354c --- /dev/null +++ b/avrdude.vcxproj @@ -0,0 +1,267 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {718DDC4C-324E-485F-BE18-2D211659A2F4} + avrdude + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + Level3 + true + + + Console + true + + + + + WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + Level3 + true + + + Console + true + + + + + WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + Level3 + true + true + true + MultiThreaded + + + Console + true + true + true + + + + + WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + Level3 + true + true + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CONFIG_DIR=".";__STDC_VERSION__=199901L;%(PreprocessorDefinitions) + CONFIG_DIR=".";__STDC_VERSION__=199901L;%(PreprocessorDefinitions) + CONFIG_DIR=".";__STDC_VERSION__=199901L;%(PreprocessorDefinitions) + CONFIG_DIR=".";__STDC_VERSION__=199901L;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {a2d07885-a0d1-473b-83b2-209cd008ee8f} + + + {17054837-6ae6-44d7-914d-9625edef4657} + + + {22615ec5-9dbc-4538-9c01-2cd535b3810b} + + + + + + \ No newline at end of file diff --git a/avrdude.vcxproj.filters b/avrdude.vcxproj.filters new file mode 100644 index 00000000..140281c0 --- /dev/null +++ b/avrdude.vcxproj.filters @@ -0,0 +1,332 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {be5ce6e6-223e-4d41-8915-29103d899c5a} + + + {dbbd7498-e1e9-4d80-b91f-137dc5b988f1} + + + {1cc9d4fb-f03f-48cb-8af7-3e96681dc03b} + + + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 1 Source Files + + + 3 Generated Files + + + 3 Generated Files + + + 4 msvc + + + 4 msvc + + + 4 msvc + + + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 2 Header Files + + + 3 Generated Files + + + 3 Generated Files + + + 4 msvc + + + 4 msvc + + + 4 msvc\sys + + + 4 msvc + + + \ No newline at end of file diff --git a/avrftdi_private.h b/avrftdi_private.h index e89d250e..177f8ca6 100644 --- a/avrftdi_private.h +++ b/avrftdi_private.h @@ -16,7 +16,11 @@ /* ftdi.h includes usb.h */ #include #else +#ifdef _MSC_VER +#pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.") +#else #warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again. +#endif #define DO_NOT_BUILD_AVRFTDI #endif diff --git a/clean.bat b/clean.bat new file mode 100644 index 00000000..2386ebfd --- /dev/null +++ b/clean.bat @@ -0,0 +1,62 @@ +@echo off +rmdir /s /q ".vs" >nul 2>nul + +rmdir /s /q "Debug" >nul 2>nul +rmdir /s /q "Release" >nul 2>nul +rmdir /s /q "x64" >nul 2>nul + +rmdir /s /q "external\libelf\Debug" >nul 2>nul +rmdir /s /q "external\libelf\Release" >nul 2>nul +rmdir /s /q "external\libelf\x64" >nul 2>nul + +rmdir /s /q "external\libhidapi\Debug" >nul 2>nul +rmdir /s /q "external\libhidapi\Release" >nul 2>nul +rmdir /s /q "external\libhidapi\x64" >nul 2>nul + +rmdir /s /q "external\libusb\Debug" >nul 2>nul +rmdir /s /q "external\libusb\Release" >nul 2>nul +rmdir /s /q "external\libusb\x64" >nul 2>nul + +rmdir /s /q .deps +rmdir /s /q .libs +rmdir /s /q autom4te.cache +rmdir /s /q m4 + +del ac_cfg.h +del ac_cfg.h.in +del aclocal.m4 +del avrdude +del avrdude.conf +del avrdude.conf.tmp +del avrdude.spec +del compile +del config.guess +del config.log +del config.status +del config.sub +del config_gram.c +del config_gram.h +del configure +del depcomp +del INSTALL +del install-sh +del lexer.c +del libtool +del ltmain.sh +del Makefile +del Makefile.in +del mdate-sh +del mkinstalldirs +del missing +del stamp-h.in +del stamp-h1 +del texinfo.tex +del y.output +del y.tab.h +del ylwrap +del *.o +del *.lo +del *.a +del *.la +del *.diff +del *.patch diff --git a/external/libelf/COPYING.LIB b/external/libelf/COPYING.LIB new file mode 100644 index 00000000..92b8903f --- /dev/null +++ b/external/libelf/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/external/libelf/ChangeLog b/external/libelf/ChangeLog new file mode 100644 index 00000000..e9b56211 --- /dev/null +++ b/external/libelf/ChangeLog @@ -0,0 +1,1435 @@ +Sun Nov 1 14:08:47 CET 2009, Michael Riepe + + * README: + * VERSION: + update for 0.8.13 release. + * libelf.pc.in: + add -I${includedir}. + * lib/begin.c: + * lib/private.h: + move archive related declarations. + * lib/elf_repl.h: + disable Elf64_Cap for 32-bit build. + * lib/getaroff.c: + new file. + * lib/Makefile.in: + * lib/Makefile.w32: + add getaroff.c. + +Tue Jul 7 19:45:12 CEST 2009, Michael Riepe + + * README: + * VERSION: + update for 0.8.12 release. + + * lib/libelf.h: + * lib/x.elfext.c: + add new and deprecate old functions. + +Fri May 22 19:17:14 CEST 2009, Michael Riepe + + * README: + * VERSION: + update for 0.8.11 release. + + * lib/libelf.h: + add ELF_F_LAYOUT_OVERLAP flag. + + * lib/rawfile.c: + fix re-read zero size bug. + + * lib/update.c: + honor ELF_F_LAYOUT_OVERLAP flag. + +Fri Sep 7 14:04:20 CEST 2007, Michael Riepe + + * acconfig.h: + add ENABLE_SANITY_CHECKS. + + * aclocal.m4: + fix --enable-gnu-names. + + * configure.in: + add --enable-sanity-checks. + fix --enable-extended-format. + + * lib/data.c: + add _elf_sanity_checks variable. + + * lib/private.h: + declare _elf_sanity_checks and constants. + + * lib/strptr.c: + enable/disable sanity check. + + * lib/version.c: + set _elf_sanity_checks from $LIBELF_SANITY_CHECKS. + +Fri Jun 29 23:27:15 CEST 2007, Michael Riepe + + * lib/Makefile.in: + improved make -jX patch. + +Wed Jun 20 08:04:30 CEST 2007, Michael Riepe + + * lib/Makefile.in: + add "make -jX install" patch by Joel Martin. + +Tue Nov 21 21:21:12 CET 2006, Michael Riepe + + * lib/Makefile.w32: + fix Windows compilation bug. + +Thu Sep 7 17:55:42 CEST 2006, Michael Riepe + + * acconfig.h: + * aclocal.m4: + * configure.in: + * lib/config.h.w32: + * lib/gelf.h: + * lib/private.h: + * lib/sys_elf.h.in: + * lib/sys_elf.h.w32: + port to QNX Neutrino, thanks to darkelf. + +Fri Aug 25 14:46:34 CEST 2006, Michael Riepe + + * Makefile.in: + add trackinstall target. + +Mon Aug 21 20:26:47 CEST 2006, Michael Riepe + + * Makefile.in: + drop w32 from DISTSUBDIRS. + * lib/Makefile.in: + add new files to DISTFILES. + * lib/Makefile.w32: + * lib/build.bat: + * lib/config.h.w32: + * lib/libelf.def: + * lib/sys_elf.h.w32: + adopted from w32 subdirectory. + +Fri Aug 18 02:04:58 CEST 2006, Michael Riepe + + * lib/begin.c: + let getnum return a size_t. + * lib/libelf.h: + replace __value because it's a reserved word in VC++ 2005. + * lib/nlist.c: + don't declare open() on W32. + * lib/private.h: + use on W32. + * w32/Makefile.w32: + fix W32 DLL build. + * w32/build.bat: + add more examples for vcvars32.bat location. + +Fri Jul 28 00:56:00 CEST 2006, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + check for dsize == -1. + * lib/verdef.h: + * lib/verneed.h: + improve section translators. + +Tue Jul 11 18:53:00 CEST 2006, Michael Riepe + + * w32/libelf.def: + add missing functions. + +Sat Jul 8 00:50:00 CEST 2006, Michael Riepe + + * VERSION: + bump up to 0.8.9. + +Sat Jul 8 00:17:00 CEST 2006, Michael Riepe + + * lib/32.newehdr.c: + make return value compatible with Solaris. + * lib/32.newphdr.c: + handle 65535+ segments. + make return value compatible with Solaris. + * lib/cook.c: + handle 65535+ segments. + * lib/elf_repl.h: + add new definitions. + * lib/libelf.h: + add/rename functions. + * lib/newscn.c: + fix section creation (was broken in 0.8.7). + * lib/private.h: + add SHN_XINDEX and PN_XNUM in case they're missing. + centrally define LIBELF_SUCCESS and LIBELF_FAILURE. + * lib/update.c: + handle 65535+ segments. + use elf->e_phnum internally. + * lib/x.elfext.c: + add elf_getphnum(). + rename elfx_get_shnum() and elfx_get_shstrndx(). + make return values compatible with Solaris. + +Fri Jul 7 19:01:04 CEST 2006, Michael Riepe + + * VERSION: + bump up to 0.8.8. + +Fri Jul 7 18:27:25 CEST 2006, Michael Riepe + + * lib/Makefile.in: + add lib/x.elfext.c. + * lib/libelf.h: + add functions from lib/x.elfext.c. + * lib/newscn.c: + simplify _elf_update_shnum(). + +Tue Apr 25 16:26:39 CEST 2006, Michael Riepe + + * lib/gelf.h: + * lib/libelf.h: + * lib/nlist.h: + * lib/private.h: + add workaround for broken compilers. + +Mon Apr 24 16:24:32 CEST 2006, Michael Riepe + + * po/de.po: + update. + +Fri Apr 21 19:17:46 CEST 2006, Michael Riepe + + * acconfig.h: + * configure.in: + add --enable-extended-format. + * aclocal.m4: + search for msgmerge. + * lib/cook.c: + change _elf_item buffering. + handle extended format (with unusual entsize). + * lib/errors.h: + add ERROR_EHDR_SHENTSIZE and ERROR_EHDR_PHENTSIZE. + * po/Makefile.in: + use msgmerge instead of tupdate. + +Thu Oct 20 21:08:02 CEST 2005, Michael Riepe + + * lib/input.c: + * lib/update.c: + handle partial reads and writes. + +Tue Aug 16 01:48:17 CEST 2005, Michael Riepe + + * lib/begin.c: + add workaround for archive member misalignment. + * VERSION: + bump up to 0.8.7 + +Tue Jul 19 11:56:26 CEST 2005, Michael Riepe + + * README: + * w32/build.bat: + update. + * w32/libelf.def: + fix syntax. + +Tue Jun 28 00:31:24 CEST 2005, Michael Riepe + + * Makefile.in: + remove superfluous slash. + +Tue Jun 21 03:58:47 CEST 2005, Michael Riepe + + * lib/Makefile.in: + get rid of lib/pic subdir. + +Sat May 21 17:39:28 CEST 2005, Michael Riepe + + * (global): + remove my e-mail address from all copyright clauses. + +Sun May 15 23:08:30 CEST 2005, Michael Riepe + + * configure.in: + check if $CC can copile . + * lib/private.h: + #include before (fixes glibc bug). + +Sun May 8 23:40:35 CEST 2005, Michael Riepe + + * Makefile.in: + add instroot variable. + install libelf.pc. + * configure.in: + create libelf.pc. + +Sun Mar 20 15:41:22 CET 2005, Michael Riepe + + * (global): + change my e-mail address. + +Fri Jan 28 23:09:57 CET 2005, Michael Riepe + + * po/Makefile.in: + use modified gmo2msg. + * po/gmo2msg.c: + make gmo2msg output more portable. + +Thu Oct 7 11:37:09 CEST 2004, Michael Riepe + + * lib/cook.c: + only use Elf64_Shdr if __LIBELF64 is true. + +Fri Sep 17 02:55:47 CEST 2004, Michael Riepe + + * lib/elf_repl.h: + add some ABI and architecture definitions. + * w32/config.h: + manual update. + +Sat Jul 10 17:33:15 CEST 2004, Michael Riepe + + * acconfig.h: + * aclocal.m4: + * lib/errmsg.c: + check for dgettext, not for gettext. + * configure.in: + check for -lintl. + * po/Makefile.in: + use -lintl when building gmo2msg. + +Sun Jul 4 23:57:21 CEST 2004, Michael Riepe + + * Makefile.in: + add w32 subdir. + * README: + update for 0.8.6. + * configure.in: + create w32/Makefile. + +Sat Jul 3 20:42:00 CEST 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + give up on . + * lib/getarsym.c: + +Wed Jun 23 01:07:46 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue May 4 22:02:01 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue Mar 30 15:09:00 CEST 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + use to work around W32 compiler problems. + +Mon Feb 16 06:19:11 CET 2004, Michael Riepe + + * Makefile.in: + generate old-format tar file. + +Sat Jan 24 03:42:39 CET 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + replace NULL with 0 -- some compilers don't like (void*). + * lib/getarsym.c: + * lib/nlist.c: + add cast to suppress compiler warning. + +Fri Jan 23 05:11:46 CET 2004, Michael Riepe + + * lib/update.c: + #undef max before #define. + +Wed Jan 21 18:15:50 CET 2004, Michael Riepe + + * lib/begin.c: + better support for Cygwin .lib archive files. + +Mon Jan 19 15:36:21 CET 2004, Michael Riepe + + * lib/libelf.h: + * lib/memset.c: + include unconditionally. + +Fri Jan 16 23:13:25 CET 2004, Michael Riepe + + * aclocal.m4: + support Intel C Compiler. + * lib/32.newehdr.c: + * lib/32.newphdr.c: + remove elf->e_free_ehdr and elf->e_free_phdr. + * lib/cook.c: + always allocate ehdr and phdr. + * lib/end.c: + always deallocate ehdr and phdr. + * lib/private.h: + remove elf->e_free_ehdr and elf->e_free_phdr. + change valid_type to suppress compiler warning. + * lib/update.c: + not necessary to update elf->e_ehdr and elf->e_phdr. + +Thu Jan 15 22:43:00 CET 2004, Michael Riepe + + * VERSION: + bump up to 0.8.6. + * configure.in: + check for __int64. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/gelf.h: + * lib/nlist.h: + test _WIN32 macro. + * lib/begin.c: + add (off_t) cast to suppress compiler warning. + * lib/libelf.h: + * lib/memset.c: + conditionally include for size_t. + * lib/nlist.c: + declare open() on W32 systems. + +Tue Dec 16 20:02:30 CET 2003, Michael Riepe + + * Makefile.in: + let disttest target make dist again. + +Sat Dec 13 16:14:31 CET 2003, Michael Riepe + + * lib/update.c: + call lseek before ftruncate. + +Fri Dec 5 16:25:16 CET 2003, Michael Riepe + + * aclocal.m4: + add explanation for --enable-maintainer-mode + * lib/Makefile.in: + * po/Makefile.in: + add instroot make variable + * README: + add hint how to use it + +Thu Nov 6 17:35:00 CET 2003, Michael Riepe + + * Makefile.in: + * lib/Makefile.in: + * po/Makefile.in: + add check targets + add MANIFEST to distribution + * aclocal.m4: + add mr_PACKAGE macro + * configure.in: + use mr_PACKAGE macro + +Sat Oct 25 15:22:59 CEST 2003, Michael Riepe + + * lib/elf_repl.h: + add EM_SPARC64 + +Thu Oct 9 23:08:56 CEST 2003, Michael Riepe + + * lib/x.movscn.c: + * lib/x.remscn.c: + verify that file is really an ELF file + +Wed Oct 8 17:10:09 CEST 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Sat May 24 18:55:14 CEST 2003, Michael Riepe + + * config.guess: + latest version from FSF + * lib/Makefile.in: + * lib/libelf.h: + * lib/x.movscn.c: + * lib/x.remscn.c: + add elfx_movscn() and elfx_remscn() + * lib/newscn.c: + update e_shnum properly + * lib/private.h: + declare _elf_update_shnum() + +Fri May 23 18:25:48 CEST 2003, Michael Riepe + + * aclocal.m4: + provide name suffixes only + * lib/Makefile.in: + use name suffixes + +Fri May 23 01:24:26 CEST 2003, Michael Riepe + + * README: + update for 0.8.5 + add section about LFS + * config.guess: + latest version from FSF + * configure.in: + * lib/Makefile.in: + use local pic object directory + * lib/checksum.c: + detect d_buf == NULL + +Sun May 18 16:49:10 CEST 2003, Michael Riepe + + * VERSION: + bump up to 0.8.5 + * lib/strptr.c: + make elf_strptr() work safely with fragmented string tables + * lib/errors.h: + new error code and message for elf_strptr() + * po/de.po: + * po/libelf.po: + regenerated + +Mon May 12 15:29:12 CEST 2003, Michael Riepe + + * lib/update.c: + improved fix for elf_update `null buffer' bug + +Mon May 12 00:34:44 CEST 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Sun May 11 01:44:06 CEST 2003, Michael Riepe + + * lib/verdef.h: + * lib/verneed.h: + fix elf_update `null buffer' error. + Thanks to Bart Trojanowski who reported the bug. + +Wed May 7 20:26:17 CEST 2003, Michael Riepe + + * configure.in: + fix maintainer mode default + * lib/verdef.h: + * lib/verneed.h: + only check d_buf if there is at least one element + +Mon Mar 31 17:08:04 CEST 2003, Michael Riepe + + * VERSION: + bump up to 0.8.4 + +Sun Mar 23 16:06:43 CET 2003, Michael Riepe + + * configure.in: + fix --enable-compat + +Thu Feb 27 14:35:12 CET 2003, Michael Riepe + + * Makefile.in: + add `test-dist' target + * lib/errors.h: + new error code + * po/de.po: + * po/libelf.pot: + regenerated + +Wed Feb 26 17:48:58 CET 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Wed Jan 15 22:50:53 CET 2003, Michael Riepe + + * lib/begin.c: + fix overflow check + +Sun Jan 12 04:27:31 CET 2003, Michael Riepe + + * configure.in: + prefer int for __libelf_i32_t (if int has 32 bits) + +Thu Jan 2 17:40:22 CET 2003, Michael Riepe + + * README: + update for 0.8.3 + * config.guess: + * config.sub: + update from ftp.gnu.org + * lib/cook.c: + require space for one SHDR only + * lib/elf_repl.h: + fix DT_ENCODING value + +Tue Dec 31 16:27:19 CET 2002, Michael Riepe + + * lib/cook.c: + honor ELF extensions for >= 0xff00 sections + * lib/elf_repl.h: + add definitions from lates ELF spec + * lib/errors.h: + * po/libelf.pot: + * po/de.po: + new error message + * lib/private.h: + define missing pieces + * lib/update.c: + handle >= 0xff00 sections + +Mon Dec 23 00:23:20 CET 2002, Michael Riepe + + * lib/Makefile.in: + fix dependencies. + * lib/cook.c: + add quirks mode for broken 64-bit architectures. + * lib/update.c: + do not override sh_entsize unless it's set to 0. + * lib/verdef.h: + * lib/verneed.h: + work around possible SEGV in translation routines. + +Sat Dec 14 23:33:10 CET 2002, Michael Riepe + + * ChangeLog: + add missing entries for 0.8.2 release. + * VERSION: + bump up to 0.8.3. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/verdef.h: + * lib/verneed.h: + fix ISO C violations (required for MacOS X). + * po/gmo2msg.c: + create SUSv3 compliant .msg files. + +Thu Jun 11 19:00:19 CEST 2002, Michael Riepe + + * README: + update for 0.8.2. + * VERSION: + bump up to 0.8.2. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + fix typos in for loop. + * lib/nlist.c: + add O_BINARY to file mode + (defaults to 0 on systems that lack it). + +Tue Dec 25 14:42:51 CET 2001, Michael Riepe + + * VERSION: + set version to 0.8.0. + * README: + update version. + +Tue Oct 30 17:05:03 CET 2001, Michael Riepe + + * Makefile.in: + use uid/gid=0 when creating the distribution tar file. + +Mon Oct 15 23:47:10 CEST 2001, Michael Riepe + + * configure.in: + check for and . + create ./pic when configuring. + * lib/Makefile.in: + move .o to ../pic/$@, not ../pic. + * lib/begin.c: + define struct ar_hdr and friends if is missing. + use lseek(..., SEEK_END). + * lib/input.c: + use lseek(..., SEEK_SET). + * lib/nlist.c: + include conditionally. + define O_RDONLY if it is missing. + * lib/private.h: + define SEEK_{SET,CUR,END} if they're missing. + * lib/update.c: + explicitly pass file descriptor to _elf_output(). + use lseek(..., SEEK_SET). + +Tue Oct 9 22:46:01 CEST 2001, Michael Riepe + + * aclocal.m4: + remove superfluous case. + +Mon Oct 8 17:56:04 CEST 2001, Michael Riepe + + * lib/opt.delscn.c: + handle versioning sections properly. + +Mon Oct 8 17:02:43 CEST 2001, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + override encoding when calculating the destination buffer + size for translation to a file. + +Sun Oct 7 21:31:01 CEST 2001, Michael Riepe + + * configure.in: + drop OBJS64; always compile 64-bit sources. + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + add translators for versioning structures. + * lib/Makefile.in: + drop OBJS64; add versioning support files. + * lib/errors.h: + add error codes for versioning support. + * lib/gelfehdr.c: + * lib/gelfphdr.c: + * lib/gelfshdr.c: + * lib/gelftrans.c: + * lib/swap64.c: + guard code with `#if __LIBELF64'. + * lib/private.h: + add translator declarations. + * po/de.po: + * po/libelf.pot: + add error messages for versioning support. + +Sun Oct 7 16:54:15 CEST 2001, Michael Riepe + + * acconfig.h: + * configure.in: + improve auto-configuration. + * lib/Makefile.in: + * po/Makefile.in + let users override distdir. + * lib/cook.c: + improved bugfix based on new auto-configuration. + * lib/getdata.c: + prepare src first to prevent SEGV. + * lib/private.h: + * lib/update.c: + cosmetic changes. + +Sun Oct 7 05:50:19 CEST 2001, Michael Riepe + + * configure.in: + * lib/cook.c: + fix compilation problem on Linux (SHT_SUNW_ver* undefined). + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + make translator functions calculate the destination size. + add _elf32_xltsize and _elf64_xltsize entry points. + * lib/private.h: + declare _elf32_xltsize and _elf64_xltsize. + * lib/getdata.c: + * lib/update.c: + use _elf32_xltsize and _elf64_xltsize. + +Fri Oct 5 20:35:31 CEST 2001, Michael Riepe + + * lib/elf_repl.h: + add DT_VERSYM. + * lib/ext_types.h: + correct type names. + * lib/libelf.h: + add ELF_T_VDEF and ELF_T_VNEED. + * lib/32.fsize.c: + add table entries for versioning structures. + * lib/cook.c: + replace _elf_scn_types[] with _elf_scn_type(). + * lib/private.h: + likewise; also remove valid_scntype() macro. + * lib/update.c: + call _elf_scn_type(), but do not set sh_entsize + for ELF_T_VDEF / ELF_T_VNEED. + * acconfig.h: + * lib/sys_elf.h.in: + added __LIBELF_SYMBOL_VERSIONS. + * configure.in: + check for symbol versioning definitions. + * lib/Makefile.in: + added gelf.h dependency. + +Wed Oct 3 22:46:33 CEST 2001, Michael Riepe + + * lib/swap64.c: + new file; separate 64-bit functions. + * lib/64.xlatetof.c: + remove 64-bit conversion functions. + * lib/byteswap.h: + replace casts to long / unsigned long. + add prototypes for 64-bit conversion functions. + * configure.in: + * lib/Makefile.in: + add lib/swap64.c. + * lib/ext_types.h: + add type definitions for versioning. + * lib/elf_repl.h: + * lib/gelf.h: + cosmetic changes. + +Wed Oct 3 00:00:27 CEST 2001, Michael Riepe + + * lib/elf_repl.h: + added lots of new definitions. + * lib/gelf.h: + * lib/libelf.h: + * lib/sys_elf.h.in: + cosmetic changes. + +Fri Sep 28 22:42:36 CEST 2001, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + remove `const' when compiling with -fPIC. + +Fri Sep 28 20:14:42 CEST 2001, Michael Riepe + + * README: + add pointers to documentation. + * lib/64.xlatetof.c: + fixed conversion thinko. + (Jakub Jelinek found this - thanks!) + * lib/gelf.h: + * lib/32.fsize.c: + add gelf_msize. + * lib/libelf.h: + add comment that elf{32,64}_checksum is missing. + +Tue Sep 11 02:43:47 CEST 2001, Michael Riepe + + * README: + corrected typo. + * lib/cook.c: + * lib/private.h: + * lib/update.c: + replaces _ELFxx_ALIGN_xHDR with _fsize() call. + +Sun Sep 2 20:58:09 CEST 2001, Michael Riepe + + * Makefile.in: + * configure.in: + * lib/Makefile.in: + * po/Makefile.in: + add maintainer mode. + +Sat Sep 1 15:11:42 CEST 2001, Michael Riepe + + * lib/sys_elf.h.in: add more fixes for broken files. + +Sat Sep 1 05:01:16 CEST 2001, Michael Riepe + + * ChangeLog: major update. Yes, I'm back. + + * COPYING.LIB: updated version from FSF. + + * README: updated for 0.7.1. + +Thu Apr 20 17:09:41 CEST 2000, Michael Riepe + + * lib/gelftrans.c: + * lib/elf_repl.h: + add explicit casts to ELF64_R_SYM and ELF64_R_INFO. + +Thu Apr 13 20:15:45 CEST 2000, Michael Riepe + + * lib/update.c: better checks for overlapping sections. + + * lib/errors.h: + * po/de.po: + * po/libelf.pot: + new error message. + +Thu Apr 6 19:15:46 CEST 2000, Michael Riepe + + * lib/strptr.c: rename `sd' variable. + +Fri Mar 31 20:11:14 CEST 2000, Michael Riepe + + * Makefile.in: also pass CPPFLAGS and LDFLAGS to config.status. + +Fri Mar 31 20:02:55 CEST 2000, Michael Riepe + + * aclocal.m4: add -DPIC define when building position-independent code. + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/errmsg.c: + make array members const when PIC is undefined. + +Fri Mar 31 14:42:32 CEST 2000, Michael Riepe + + * lib/32.newehdr.c: make _elf_newehdr() function private again. + + * lib/32.newphdr.c: make _elf_newphdr() function private again. + + * lib/strptr.c: add support for 64-bit ELF format. + +Wed Mar 29 18:49:43 CEST 2000, Michael Riepe + + * lib/gelfshdr.c: remove ELF class check. + +Mon Mar 27 01:24:50 CEST 2000, Michael Riepe + + * lib/gelf.h: #include when compiling libelf. + +Sun Mar 26 15:02:54 CEST 2000, Michael Riepe + + * lib/private.h: #include header file. + + * lib/gelfehdr.c: move gelf_newehdr() function to lib/32.newehdr.c. + + * lib/gelfphdr.c: move gelf_newphdr() function to lib/32.newphdr.c. + + * lib/32.newehdr.c: add gelf_newehdr() function. + + * lib/32.newphdr.c: add gelf_newphdr() function. + + * lib/gelfshdr.c: + * lib/gelftrans.c: + remove explicit include. + +Sun Mar 26 06:22:20 CEST 2000, Michael Riepe + + * acconfig.h: + * configure.in: + * lib/private.h: + * lib/sys_elf.h.in: + rename NEED_LINK_H to __LIBELF_NEED_LINK_H. + + * lib/32.newehdr.c: make _elf_newehdr() function public. + + * lib/32.newphdr.c: make _elf_newphdr() function public. + + * lib/gelf.h: + include if needed. + choke if 64-bit is not supported. + add generic versions of ELF32_* and ELF64_* macros. + + * lib/gelftrans.c: + define ELF32_R_* and ELF64_R_* macros (missing on some systems). + +Sun Mar 26 05:27:15 CEST 2000, Michael Riepe + + * configure.in: + add check for existing header. + build new source files when 64-bit is enabled. + + * lib/Makefile.in: + add new source files. + make install-compat if --enable-compat was given. + + * po/de.po: + * po/libelf.pot: + new error messages. + +Sun Mar 26 05:00:20 CEST 2000, Michael Riepe + + * Makefile.in: + * lib/Makefile.in: + * po/Makefile.in: + remove Makefile last in `make distclean'. + + * aclocal.m4: explicitly state the default in --enable-* help texts. + + * configure.in: + set ALL_LINGUAS automatically. + add `--enable-compat' option. + + * lib/private.h: add sd_scn member to struct Scn_Data. + + * lib/cook.c: + * lib/end.c: + * lib/getdata.c: + * lib/newdata.c: + * lib/opt.delscn.c: + * lib/rawdata.c: + * lib/update.c: + handle new sd_scn member. + + * lib/gelf.h: new public header file. + + * lib/gelfehdr.c: new file, implements the gelf_getehdr(), + gelf_update_ehdr() and gelf_newehdr() functions. + + * lib/gelfphdr.c: new file, implements the gelf_getphdr(), + gelf_update_phdr() and gelf_newphdr() functions. + + * lib/gelfshdr.c: new file, implements the gelf_getshdr() + and gelf_update_shdr() functions. + + * lib/gelftrans.c: new file, implements the gelf_getsym(), + gelf_update_sym(), gelf_getdyn(), gelf_update_dyn(), + gelf_getrela(), gelf_update_rela(), gelf_getrel() and + gelf_update_rel() functions. + + * lib/begin.c: add gelf_getclass() function. + + * lib/32.fsize.c: add gelf_fsize() function. + + * lib/32.getphdr.c: make _elf_getphdr() function public. + + * lib/64.xlatetof.c: + add gelf_xlatetom() and gelf_xlatetof() functions. + remove `const' from array members. + + * lib/errors.h: add GElf error messages. + + * po/de.po: + * po/libelf.pot: + new error message. + +Thu Nov 4 21:17:34 CET 1999, Michael Riepe + + * lib/32.xlatetof.c: + * lib/errmsg.c: + * po/gmo2msg.c: + remove `const' from array members. + +Thu Nov 4 20:16:36 CET 1999, Michael Riepe + + * lib/Makefile.in: add assert.c; remove stamp-h in `make distclean'. + + * lib/assert.c: new file, implements the __elf_assert() function. + + * lib/private.h: use __elf_assert() in elf_assert() macro. + +Wed Mar 17 16:21:02 CET 1999, Michael Riepe + + * configure.in: add "de" to ALL_LINGUAS. + + * lib/elf_repl.h: lots of new #defines. + + * lib/hash.c: + * lib/libelf.h: + elf_hash() takes an `const unsigned char *'. + + * po/gmo2msg.c: copy comments from .gmo file. + +Fri Mar 5 16:28:08 CET 1999, Michael Riepe + + * VERSION: set version to 0.7.1. + + * po/de.po: new file. + +Fri Nov 27 22:24:00 MET 1998, Michael Riepe + + * lib/memset.c: rename and rewrite. + * lib/private.h: rename __memset. + +Tue Aug 25 17:17:18 MEST 1998, Michael Riepe + + * aclocal.m4: remove superfluous #include. + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: fix for picky instances of cpp(1). + +Sun Aug 23 18:26:53 MEST 1998, Michael Riepe + + * aclocal.m4: + * lib/Makefile.in: add DEPSHLIBS, set to -lc for Linux. + + * README: add DEPSHLIBS description. + +Sat Aug 22 15:50:41 MEST 1998, Michael Riepe + + * lib/begin.c: add workaround for broken ar(1) & friends. + + * lib/32.getshdr.c: fix typo. + +Thu Aug 6 18:11:52 MEST 1998, Michael Riepe + + * lib/getdata.c: fixed SEGV bug. + + * lib/cook.c: + * lib/getdata.c: + * lib/newdata.c: + * lib/rawdata.c: + * lib/private.h: removed sd_scn and (Elf_Data*) casts. + +Fri Jun 12 21:24:50 MEST 1998, Michael Riepe + + * lib/*.c: move rcsid[] after . + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: replace broken Exn() macro with Cat2(). + + * lib/64.xlatetof.c: change `char*' to `unsigned char*'. + + * lib/private.h: add `extern char *realloc();'. + + * aclocal.m4: + * configure.in: remove leading spaces in cpp directives. + +Sun Jun 7 16:02:31 MEST 1998, Michael Riepe + + * README: update for 0.7.0 release. + +Sun Jun 4 15:26:49 MEST 1998, Michael Riepe + + * acconfig.h: add __libelf64* and __libelf_*_t. + + * configure.in: clean up, add checks for 64-bit support. + + * lib/64.xlatetof.c: new file, based on lib/32.xlatetof.c. + + * lib/Makefile.in: add target for 64.xlatetof.o. + + * lib/cook.c: check for 32-bit overflow. + + * lib/elf_repl.h: + * lib/ext_types.h: add 64-bit data types. + + * lib/private.h: add 64-bit definitions. + + * lib/sys_elf.h.in: add __LIBELF64* and __libelf_*_t. + + * lib/update.c: add full 64-bit support. + +Mon Jun 1 16:29:07 MEST 1998, Michael Riepe + + * VERSION: change version to 0.7.0. + + * configure.in: + add lib/sys_elf.h to AC_CONFIG_HEADER. + new option --disable-elf64. + + * Makefile.in: add target for lib/sys_elf.h. + + * acconfig.h: add __LIBELF_HEADER_ELF_H. + + * lib/Makefile.in: add sys_elf.h(.in). + + * lib/32.fsize.c: + * lib/32.getehdr.c: + * lib/32.getphdr.c: + * lib/32.getshdr.c: + * lib/32.newehdr.c: + * lib/32.newphdr.c: + * lib/cook.c: + * lib/getdata.c: + * lib/libelf.h: + * lib/newscn.c: + * lib/nlist.c: + * lib/opt.delscn.c: + * lib/private.h: + * lib/update.c: + merged with 64bit code. + + * lib/begin.c: + * lib/input.c: + bug fixes. + +Fri Aug 1 19:33:33 MEST 1997, Michael Riepe + + * VERSION: change version to 0.6.5. + + * lib/libelf.h: add declaration for elf_memory. + + * lib/private.h: add e_memory flag. + + * lib/begin.c: add elf_memory, change archive freezing logic. + + * lib/end.c: do not free e_data if e_memory is set. + +Tue Oct 22 21:31:56 MEST 1996, Michael Riepe + + * (all files): add RCS Id, import to CVS. + + * Makefile.in: pass $(CC) to config.status. + + * README: change for upcoming 0.6.5 release. + + * aclocal.m4 (mr_ENABLE_NLS): add --enable-gnu-names option + + * configure.in: change search order for . + + * lib/begin.c (_elf_arhdr): add check for truncated archive member. + + * lib/cook.c (_elf32_cook): add checks for misaligned tables. + + * lib/errors.h: + fix wrong error message (ERROR_WRONLY). + add error messages for misaligned tables. + + * lib/private.h: add constants for table alignments. + + * po/Makefile.in: do not run mkinstalldirs directly, use $(SHELL). + + * po/libelf.pot: rebuild. + +Tue Jul 30 17:22:41 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.4. + + * Makefile.in: + add DISTSUBDIRS. + add po/Makefile target. + + * po/Makefile.in: + * po/gmo2msg.c: + * po/libelf.pot: + * po/stamp-po: + new files. + + * aclocal.m4 (mr_ENABLE_NLS): + add MSGFILES. + set GMOFILES, MSGFILES and POFILES even if NLS is disabled. + + * configure.in: + add ALL_LINGUAS. + + * lib/nlist.c: + call elf_errno() to clear pending error. + +Tue Jul 28 23:53:44 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.3. + + * configure.in: fix creation of sys_elf.h. + + * lib/Makefile.in: + move elf_repl.h to PRIVHDRS. + do not depend on HDRS and AUXHDRS. + +Sat Jul 27 18:27:09 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.2. + + * Makefile.in: + remove support from SUBDIRS. + remove subdirs/Makefile target. + + * acconfig.h: + add ENABLE_DEBUG. + remove HAVE_NLS. + + * aclocal.m4: + add mr_ENABLE_DEBUG. + + * configure.in: + use mr_ENABLE_DEBUG. + + * lib/Makefile.in: + add LD variable. + add elf_repl.h to DISTFILES. + + * lib/libelf.h: + add check for __LIBELF_INTERNAL__. + + * lib/private.h: + #define __LIBELF_INTERNAL__. + use ENABLE_DEBUG. + + * support/elf.h: + move to lib/elf_repl.h. + + * support/Makefile.in: + remove. + +Sat Jul 27 06:25:23 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.1. + + * aclocal.m4: add shared library support for sparc-sun-solaris2. + + * lib/libelf.h.in: remove. + + * lib/libelf.h: new file. + + * configure.in: + remove broken check for existing installation. + remove @install_headers@ and @elf_h@. + do not build libelf.h from libelf.h.in. + create lib/sys_elf.h. + + * lib/Makefile.in: + remove libelf.h and $(AUXHDRS) targets. + remove libelf.h.in from DISTFILES. + add libelf.h to DISTFILES. + add dummy_shlib target for broken make. + +Sat Jul 27 01:01:45 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.6.0. + + * lib: new directory. + + * config.sub: + * config.guess: + new files. + + * shared: + * shared/Makefile.in: + remove. + + * aclocal.m4: + * configure.in: + add shared library check. + + * Makefile.in: + * lib/Makefile.in: + change for new directory structure. + integrate shared library support. + + * Makefile.in: + remove libelf.lsm from DISTFILES. + + * libelf.lsm: remove. + +Thu Jul 25 19:35:05 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.9. + + * aclocal.m4: rewrite NLS check. + +Tue Jul 23 18:59:05 MET DST 1996, Michael Riepe + + * Makefile.in: add install-compat and uninstall-compat targets. + + * configure.in: + * aclocal.m4: + fix check for NLS support. + + * acconfig.h: add HAVE_CATGETS and HAVE_GETTEXT. + + * errmsg.c (elf_errmsg): use HAVE_GETTEXT. + +Sun Jul 21 22:52:02 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.8. + + * private.h: + * 32.getshdr.c: + * cook.c: + * end.c: + * newscn.c: + * opt.delscn.c: + * update.c: + change allocation of section headers. + + * errors.h: fix speeling error. + +Sat Jul 13 22:51:16 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.7. + + * private.h: add e_dsize member to struct Elf. + + * begin.c (elf_begin): set e_dsize. + + * update.c (_elf32_update_pointers): + never let e_data become shorter than e_dsize bytes. + use correct base pointer. + +Sat Jun 15 16:28:50 MET DST 1996, Michael Riepe + + * 32.xlatetof.c: change `char' to `unsigned char'. + +Tue May 28 19:00:30 MET DST 1996, Michael Riepe + + * Makefile.in: + HP-UX make wants non-empty target, change it. + add targets for TAGS and libelf.po. + + * errors.h: mark strings for GNU gettext. + + * mkmsgs: recognize new errors.h format. + + * errmsg.c (elf_errmsg): add gettext support. + +Mon May 27 20:30:30 MET DST 1996, Michael Riepe + + * VERSION: change version to 0.5.6. + + * aclocal.m4: + * configure.in: use new AC_CACHE_CHECK macro. + + * Makefile.in: + * shared/Makefile.in: use @...dir@. + + * Makefile.in: pass $(SRCS) and $(OBJS) to shared/Makefile. + +Sat May 25 01:00:15 MET DST 1996, Michael Riepe + + * update.c (elf_update): assert e_data is malloc'ed. + + * begin.c (elf_begin): mmap e_data if possible. + + * end.c (elf_end): munmap e_data if necessary. + + * input.c (_elf_mmap): new function. + + * private.h: add _elf_mmap and e_unmap_data. + + * errmsg.c: make pointer array constant. + +Thu May 23 19:24:47 MET DST 1996, Michael Riepe + + * update.c (elf_update): mmap(MAP_SHARED) wants non-empty file. + +Tue May 21 15:33:07 MET DST 1996, Michael Riepe + + * begin.c (elf_begin): re-read memory image of archive members. + + * cook.c (_elf32_item): + * getdata.c (_elf32_cook_scn): always use memory image. + + * update.c (_elf_update): use mmap if possible. + + * configure.in: check for mmap. + +Mon May 20 18:15:54 MET DST 1996, Michael Riepe + + * nlist.c (_elf_nlist): fix broken st_name range check. + + * update.c (_elf32_write): check status of elf_getdata. + + * cook.c (_elf32_item): + * getdata.c (_elf32_cook_scn): + use memory image when file is not an archive member. + + * rawdata.c (elf_rawdata): copy raw image rather than referencing it. + +Wed May 15 20:04:39 MET DST 1996, Michael Riepe + + * rawdata.c (elf_rawdata): use raw image if it is present. + + * cntl.c (elf_cntl): fix archive handling, ignore ELF_C_FDREAD for non-ELF files. + +Fri May 10 17:16:44 MET DST 1996, Michael Riepe + + * begin.c (_elf_arhdr): fix handling of long archive member names. + + * configure.in: move version information to external file. + + * Makefile.in: add VERSION to DISTFILES. + + * VERSION: new file. + +Sat May 4 20:56:43 MET DST 1996, Michael Riepe + + * configure.in: change version to 0.5.5. + + * Makefile.in: add libelf.lsm and ChangeLog to DISTFILES. + + * rawdata.c: reorder cases to avoid unnecessary malloc/free. + + * all files: update copyright phrase. + + * ChangeLog: + * libelf.lsm: new files. + +Sun Oct 29 19:34:00 MET 1995, Michael Riepe + + * configure.in: change version to 0.5.3. + + * Makefile.in: + * shared/Makefile.in: add opt.delscn.c. + + * libelf.h.in: add declaration for elf_delscn. + + * opt.delscn.c: new file. + diff --git a/external/libelf/README b/external/libelf/README new file mode 100644 index 00000000..b4f9d951 --- /dev/null +++ b/external/libelf/README @@ -0,0 +1,332 @@ +This is the public release of libelf-0.8.13, a free ELF object +file access library. If you have problems with applications +that use libelf and work with the commercial (SVR4, Solaris) +version but not with this one, please contact me. + +IMPORTANT NOTE: If you have libelf-0.5.2 installed, you probably +have a file .../include/elf.h that contains the single line +``#include ''. REMOVE THIS FILE BEFORE YOU RUN +configure. + +Installation is straightforward - the package is autoconf'ed. Just do +``cd libelf-0.8.13; ./configure; make; make install''. Header files +will be installed in .../include/libelf/. If your system does not +provide its own versions of libelf.h, nlist.h or gelf.h, ``make +install'' will add the missing headers. If you prefer not to have +these files installed in /usr/include, use ``--disable-compat'' and +add ``-I /usr/include/libelf'' to your CFLAGS when compiling +libelf-based programs. + +Note to distribution makers: You can install libelf in a separate root +hierarchy by using the command ``make instroot=/my/root install''. +You should also use the ``--enable-compat'' configure option in that +case, or run ``make instroot=/my/root install-compat'' manually, to +install all the required header files. + +If you are running Linux with libc 5.* as the default C library, +and you plan to use the 64-bit functions, you must either use +``-I.../include/libelf'', or remove /usr/include/libelf.h and use +``--enable-compat'' when running configure. Libc 6.* (aka glibc2) +doesn't have its own , or . + +You need an ANSI/ISO C compiler to build libelf. Gcc is optimal. + +On some systems (in particular, Solaris and all variants of Linux), +``make'' will try to build a shared library. If you run into problems +on your system, please pass ``--disable-shared'' to configure. +If you build a shared library and want it to be installed as +``libelf-0.8.13.so'' rather than ``libelf.so.0.8.13'', please use +``./configure --enable-gnu-names''. Other files, e.g. ``libelf.so'' and +``libelf.so.0'' are NOT affected. + +Another configure option, ``--enable-debug'', adds debugging code to +libelf; if you don't run into problems, you will probably not need it. + +When creating an ELF shared library, it is possible to add references +to other shared libraries in the DYNAMIC section of the resulting +file. The make variable DEPSHLIBS contains a list of libraries to add. +It is set to ``-lc'' on Linux systems, and empty otherwise. To +override this setting, use something like ``make DEPSHLIBS="-la -lb"''. +For Linux, `-lc' is included automagically. + +NLS is available and enabled by default. To turn it off, pass the +``--disable-nls'' option to configure. + +Libelf can use gettext or catgets for accessing message +catalogs. If gettext is available AND is part of libc (i.e. not +in a separate library), it will be used. Otherwise, configure +will look for catgets. If you have gettext in a separate +library and want to use it, you should pass the library's name +to configure, e.g. ``LIBS=-lintl ./configure''. Note that you +MUST link your libelf-based applications with -lintl then, +which is probably not what you want, or change the DEPSHLIBS variable +described above (in case you're building a shared library). + +If you have GNU gettext 0.10 installed on your system, and if GNU gettext +runs on top of the catgets interface (rather old Linux systems, using +libc5), configure will refuse to use it and use catgets instead. If you +absolutely want to use GNU gettext, go ahead and rebuild it (which is +IMHO a good idea in general in this case): + + cd .../gettext-0.10 + ac_cv_func_catgets=no ac_cv_func_gettext=no ./configure + make + make install + +After that, return to the libelf build directory, remove +config.cache, and start over. + +*** Large File Support (LFS) applications *** + +Some 32-bit systems support files that are larger than the address space +of the architecture. On these, the `off_t' data type may have 32 or +64 bits, depending on the API you choose. Since off_t is also part of +the libelf API, in particular the Elf_Data and Elf_Arhdr structures, +an application compiled with large file support will need a version of +libelf that has also been compiled with LFS; otherwise, it won't work +correctly. Similarly, a program compiled without LFS needs a library +compiled without LFS. + +Note that libelf is currently unable to process large files on 32-bit +architectures, whether you compile it for LFS or not, for the simple +reason that the files won't fit into the processes' address space. +Therefore, libelf is compiled without LFS by default. It can of course +read and write ELF files for 64-bit architectures, but they will be +limited in length on a 32-bit system. + +You may compile libelf with large file support by setting CPPFLAGS at +configuration time: + + CPPFLAGS=`getconf LFS_CFLAGS` ./configure + +But I really, really recommend you don't, because it breaks binary +compatibility with existing libelf based applications. + +*** 64-bit support *** + +Starting with libelf-0.7.0, libelf also supports 64-bit ELF files. +This is enabled by default unless your system (or your compiler) does +not support 64-bit integers, or lacks 64-bit declarations in . +If you have problems building with 64-bit support, please do + + ./configure --disable-elf64 + +for the moment, and contact me. Please note that I haven't tested 64-bit +support much. There are still some unresolved problems, e.g. IRIX +uses different Elf64_Rel and Elf64_Rela structures (they replaced the +r_info member), and the enumeration values for Elf_Type differ from +the commercial (SVR4) implementation of libelf - they broke binary +compatibility for no good reason, and I'm not willing to follow their +footsteps. The result is that libelf-0.7.* ist upward compatible with +libelf-0.6.4 (as it should be) but INCOMPATIBLE WITH SVR4 LIBELF. If you +have both versions installed, you'd better make sure that you link with +the library that matches the you're #include'ing. + +*** Symbol Versioning *** + +Libelf >= 0.8.0 supports the data structures and definitions used for +symbol versioning on Solaris and Linux, in particular, the Elfxx_Verdef, +Elfxx_Verdaux, Elfxx_Verneed, Elfxx_Vernaux and Elfxx_Versym structures +and the SHT_XXX_verdef, SHT_XXX_verneed and SHT_XXX_versym section types +(where `xx' is either `32' or `64', and `XXX' is either `SUNW' or `GNU'). +Libelf now translates versioning sections to/from their external +representation properly (earlier versions left them in `raw' format, +with the data type set to ELF_T_BYTE). This may cause problems on +systems which use the same (OS-specific) section types for different +purposes. The configure program tries to figure out if your OS uses +versioning; if that check fails, you can use + + ./configure --disable-versioning + +to turn off versioning translation support. + +*** W32 Support *** + +There is now some support for building on W32 systems (requires Microsoft +VC++). In order to build a W32 DLL, cd into the `lib' subdirectory, edit +build.bat if necessary (it needs the path to your compiler binaries) and +run it. If you're lucky, libelf.dll and the import/export libraries will +be built. If not, please drop me a line. + +I tested it on XP Pro (SP2), using VC++ 2005 Express Edition. +Apparently, Visual Studio .NET 2003 works fine as well. + +Various notes regarding the W32 port: + + - When you open() an ELF file, remember to use the O_BINARY flag. + - You may have to add /MD to the linker command line. + +*** Missing things *** + + * There is no documentation. You can use the Solaris + manpages instead (available at http://docs.sun.com/). + The ELF file format is described in several places; + among them Suns "Linker and Libraries Guide" and the + "System V Application Binary Interface" documents; + http://www.caldera.com/developer/devspecs/gabi41.pdf and + http://www.caldera.com/developer/gabi/ are probably good + starting points. Processor-specific documentation is spread + across a number of `Processor Supplement' documents, one + for each architecture; you'll have to use a search engine to + find them. + + * The COFF file format is not understood. This is so obsolete + that it will probably never be implemented. + + * nlist(3) is incomplete; the n_type and n_sclass + members of struct nl are set to zero even if type + (that is, debug) information is available. + + * Libelf does not translate Solaris' `Move' and `Syminfo' + sections. You can read them using elf_getdata(), but you'll + only get raw (untranslated) bytes. + +Changes since 0.8.12: + + * New function elf_getaroff(). + + * Build fixes. + +Changes since 0.8.11: + + * Due to some unfortunate confusion, the elf_getphnum(), + elf_getshnum() and elf_getshstrndx() are not compatible + between libelf implementations. Therefore, the developers + decided to replace them with new functions: elf_getphdrnum(), + elf_getshdrnum() and elf_getshdrstrndx(), which will always + return -1 on failure and 0 on success. Code using the old + interface should be upgraded to increase portability. + +Changes since 0.8.10: + + * Fixed a bug in elf_rawfile(). + * If you use ELF_F_LAYOUT together with ELF_F_LAYOUT_OVERLAP, + elf_update() will now tolerate overlapping sections. + +Changes since 0.8.9: + + * Ported to QNX Neutrino. + * Fixed Windows build errors. + * Parallel (make -j) installation should work now. + + * It's now possible to enable and disable select sanity checks + libelf performs. Currently, this affects the "NUL terminated + string table entry" check performed in elf_strptr(). By + default, the function will return an error if the string + requested is not properly terminated - because some + applications might dump core otherwise. If you configure + libelf with `--disable-sanity-checks', however, the check + (and, in the future, probably others as well) is disabled + by default. You can still turn it on and off at runtime by + setting the LIBELF_SANITY_CHECKS environment variable to + an integer value: + + # disable all sanity checks + export LIBELF_SANITY_CHECKS=0 + + # enable all sanity checks + export LIBELF_SANITY_CHECKS=-1 + + Each bit of the value corresponds to a particular check, + so you could use LIBELF_SANITY_CHECKS=1 to enable only + the elf_strptr() check. You may also use a value in hex + (0x...) or octal (0...) format. + +Changes since 0.8.8: + + * Improved translator for symbol versioning sections. + * The W32 library is now built in the `lib' subdirectory. + * Windows DLLs should work now. + +Changes since 0.8.6: + + * added elf_getphnum(). + * added elf_getshnum(). + * added elf_getshstrndx(). + * added elfx_update_shstrndx(). + * handle interrupted reads/writes more gracefully. + * added (partial) support for unusual e_[ps]hentsize values. + * fixed the bugs introduced in 0.8.7. + +Changes since 0.8.5: + + * added W32 support. + * added workaround for alignment errors in archive members. + * my email address has changed again ;) + +Changes since 0.8.4: + + * elf_strptr() should now work more safely with fragmented + or badly formatted string tables. + +Changes since 0.8.3: + + * Fixed a bug in elf_update() that was introduced in 0.8.3. + +Changes since 0.8.2: + + * Should compile on MacOSX now. + + * Can read and write files with more than 65280 sections + + * Tries to handle 64-bit ELF files that use 8-byte hash table + entries. In particular, libelf tries to guess the data type in + elf_getdata(), and doesn't override sh_entsize in elf_update() + any longer. If you want the library to pick the entry size, + you must set its value to 0 before you call elf_update(). + + * No longer dumps core in elf_update() when a versioning section + has no data. Instead, it returns an error message. Note that + you're supposed to provide a valid d_buf for any section, unless + it's empty or has SHT_NOBITS type. + + * Building a shared library is now the default (if supported). + +Changes since 0.8.0: + + * Corrected typo in lib/{32,64}.xlatetof.c that sometimes + caused a compilation failure. + + * Use open(name, O_RDONLY|O_BINARY) in lib/nlist.c. + +Changes since 0.7.0: + + * I implemented the gelf_* interface, as found on Solaris. + I don't know whether it's compatible -- the Solaris manpage + isn't very specific, so I had to guess return values etc. in + some cases. + + * Added elf{32,64}_checksum (supposed to be compatible with + Solaris). + + * Added symbol versioning support. + +Changes since 0.6.4: + + * Fixed configure for IRIX systems + * Added check for truncated archive members + * Added check for misaligned SHDR/PHDR tables + * Support for building libelf together with GNU libc + * Added elf_memory(3) + * Added 64-bit support + +Changes since 0.5.2: + + * some bug fixes + * mmap support + * new directory layout + * There is a new function, elf_delscn(), that deletes + a section from an ELF file. It also adjusts the + sh_link and sh_info members in the section header + table, if (and ONLY if) the ELF standard indicates + that these values are section indices. References + to the deleted section will be cleared, so be careful. + * my email address has changed ;) + +Where to get libelf: + + ftp://ftp.ibiblio.org/pub/Linux/libs/ + http://www.mr511.de/software/ + +Michael "Tired" Riepe + diff --git a/external/libelf/VERSION b/external/libelf/VERSION new file mode 100644 index 00000000..c2f73c6e --- /dev/null +++ b/external/libelf/VERSION @@ -0,0 +1 @@ +0.8.13 diff --git a/external/libelf/include/libelf.h b/external/libelf/include/libelf.h new file mode 100644 index 00000000..3ebd0f3f --- /dev/null +++ b/external/libelf/include/libelf.h @@ -0,0 +1,305 @@ +/* + * libelf.h - public header file for libelf. + * Copyright (C) 1995 - 2008 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: libelf.h,v 1.29 2009/07/07 17:57:43 michael Exp $ */ + +#ifndef _LIBELF_H +#define _LIBELF_H + +#include /* for size_t */ +#include + +#if __LIBELF_INTERNAL__ +#include +#else /* __LIBELF_INTERNAL__ */ +#include +#endif /* __LIBELF_INTERNAL__ */ + +#if defined __GNUC__ && !defined __cplusplus +#define DEPRECATED __attribute__((deprecated)) +#else +#define DEPRECATED /* nothing */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef __P +# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +# define __P(args) args +# else /* __STDC__ || defined(__cplusplus) */ +# define __P(args) () +# endif /* __STDC__ || defined(__cplusplus) */ +#endif /* __P */ + +/* + * Commands + */ +typedef enum { + ELF_C_NULL = 0, /* must be first, 0 */ + ELF_C_READ, + ELF_C_WRITE, + ELF_C_CLR, + ELF_C_SET, + ELF_C_FDDONE, + ELF_C_FDREAD, + ELF_C_RDWR, + ELF_C_NUM /* must be last */ +} Elf_Cmd; + +/* + * Flags + */ +#define ELF_F_DIRTY 0x1 +#define ELF_F_LAYOUT 0x4 +/* + * Allow sections to overlap when ELF_F_LAYOUT is in effect. + * Note that this flag ist NOT portable, and that it may render + * the output file unusable. Use with extreme caution! + */ +#define ELF_F_LAYOUT_OVERLAP 0x10000000 + +/* + * File types + */ +typedef enum { + ELF_K_NONE = 0, /* must be first, 0 */ + ELF_K_AR, + ELF_K_COFF, + ELF_K_ELF, + ELF_K_NUM /* must be last */ +} Elf_Kind; + +/* + * Data types + */ +typedef enum { + ELF_T_BYTE = 0, /* must be first, 0 */ + ELF_T_ADDR, + ELF_T_DYN, + ELF_T_EHDR, + ELF_T_HALF, + ELF_T_OFF, + ELF_T_PHDR, + ELF_T_RELA, + ELF_T_REL, + ELF_T_SHDR, + ELF_T_SWORD, + ELF_T_SYM, + ELF_T_WORD, + /* + * New stuff for 64-bit. + * + * Most implementations add ELF_T_SXWORD after ELF_T_SWORD + * which breaks binary compatibility with earlier versions. + * If this causes problems for you, contact me. + */ + ELF_T_SXWORD, + ELF_T_XWORD, + /* + * Symbol versioning. Sun broke binary compatibility (again!), + * but I won't. + */ + ELF_T_VDEF, + ELF_T_VNEED, + ELF_T_NUM /* must be last */ +} Elf_Type; + +/* + * Elf descriptor + */ +typedef struct Elf Elf; + +/* + * Section descriptor + */ +typedef struct Elf_Scn Elf_Scn; + +/* + * Archive member header + */ +typedef struct { + char* ar_name; + time_t ar_date; + long ar_uid; + long ar_gid; + unsigned long ar_mode; + off_t ar_size; + char* ar_rawname; +} Elf_Arhdr; + +/* + * Archive symbol table + */ +typedef struct { + char* as_name; + size_t as_off; + unsigned long as_hash; +} Elf_Arsym; + +/* + * Data descriptor + */ +typedef struct { + void* d_buf; + Elf_Type d_type; + size_t d_size; + off_t d_off; + size_t d_align; + unsigned d_version; +} Elf_Data; + +/* + * Function declarations + */ +extern Elf *elf_begin __P((int __fd, Elf_Cmd __cmd, Elf *__ref)); +extern Elf *elf_memory __P((char *__image, size_t __size)); +extern int elf_cntl __P((Elf *__elf, Elf_Cmd __cmd)); +extern int elf_end __P((Elf *__elf)); +extern const char *elf_errmsg __P((int __err)); +extern int elf_errno __P((void)); +extern void elf_fill __P((int __fill)); +extern unsigned elf_flagdata __P((Elf_Data *__data, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagehdr __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagelf __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagphdr __P((Elf *__elf, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagscn __P((Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned __flags)); +extern unsigned elf_flagshdr __P((Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned __flags)); +extern size_t elf32_fsize __P((Elf_Type __type, size_t __count, + unsigned __ver)); +extern Elf_Arhdr *elf_getarhdr __P((Elf *__elf)); +extern Elf_Arsym *elf_getarsym __P((Elf *__elf, size_t *__ptr)); +extern off_t elf_getbase __P((Elf *__elf)); +extern Elf_Data *elf_getdata __P((Elf_Scn *__scn, Elf_Data *__data)); +extern Elf32_Ehdr *elf32_getehdr __P((Elf *__elf)); +extern char *elf_getident __P((Elf *__elf, size_t *__ptr)); +extern Elf32_Phdr *elf32_getphdr __P((Elf *__elf)); +extern Elf_Scn *elf_getscn __P((Elf *__elf, size_t __index)); +extern Elf32_Shdr *elf32_getshdr __P((Elf_Scn *__scn)); +extern unsigned long elf_hash __P((const unsigned char *__name)); +extern Elf_Kind elf_kind __P((Elf *__elf)); +extern size_t elf_ndxscn __P((Elf_Scn *__scn)); +extern Elf_Data *elf_newdata __P((Elf_Scn *__scn)); +extern Elf32_Ehdr *elf32_newehdr __P((Elf *__elf)); +extern Elf32_Phdr *elf32_newphdr __P((Elf *__elf, size_t __count)); +extern Elf_Scn *elf_newscn __P((Elf *__elf)); +extern Elf_Cmd elf_next __P((Elf *__elf)); +extern Elf_Scn *elf_nextscn __P((Elf *__elf, Elf_Scn *__scn)); +extern size_t elf_rand __P((Elf *__elf, size_t __offset)); +extern Elf_Data *elf_rawdata __P((Elf_Scn *__scn, Elf_Data *__data)); +extern char *elf_rawfile __P((Elf *__elf, size_t *__ptr)); +extern char *elf_strptr __P((Elf *__elf, size_t __section, size_t __offset)); +extern off_t elf_update __P((Elf *__elf, Elf_Cmd __cmd)); +extern unsigned elf_version __P((unsigned __ver)); +extern Elf_Data *elf32_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); +extern Elf_Data *elf32_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); + +/* + * Additional functions found on Solaris + */ +extern long elf32_checksum __P((Elf *__elf)); + +#if __LIBELF64 +/* + * 64-bit ELF functions + * Not available on all platforms + */ +extern Elf64_Ehdr *elf64_getehdr __P((Elf *__elf)); +extern Elf64_Ehdr *elf64_newehdr __P((Elf *__elf)); +extern Elf64_Phdr *elf64_getphdr __P((Elf *__elf)); +extern Elf64_Phdr *elf64_newphdr __P((Elf *__elf, size_t __count)); +extern Elf64_Shdr *elf64_getshdr __P((Elf_Scn *__scn)); +extern size_t elf64_fsize __P((Elf_Type __type, size_t __count, + unsigned __ver)); +extern Elf_Data *elf64_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); +extern Elf_Data *elf64_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src, + unsigned __encode)); + +/* + * Additional functions found on Solaris + */ +extern long elf64_checksum __P((Elf *__elf)); + +#endif /* __LIBELF64 */ + +/* + * ELF format extensions + * + * These functions return 0 on failure, 1 on success. Since other + * implementations of libelf may behave differently (there was quite + * some confusion about the correct values), they are now officially + * deprecated and should be replaced with the three new functions below. + */ +DEPRECATED extern int elf_getphnum __P((Elf *__elf, size_t *__resultp)); +DEPRECATED extern int elf_getshnum __P((Elf *__elf, size_t *__resultp)); +DEPRECATED extern int elf_getshstrndx __P((Elf *__elf, size_t *__resultp)); +/* + * Replacement functions (return -1 on failure, 0 on success). + */ +extern int elf_getphdrnum __P((Elf *__elf, size_t *__resultp)); +extern int elf_getshdrnum __P((Elf *__elf, size_t *__resultp)); +extern int elf_getshdrstrndx __P((Elf *__elf, size_t *__resultp)); + +/* + * Convenience functions + * + * elfx_update_shstrndx is elf_getshstrndx's counterpart. + * It should be used to set the e_shstrndx member. + * There is no update function for e_shnum or e_phnum + * because libelf handles them internally. + */ +extern int elfx_update_shstrndx __P((Elf *__elf, size_t __index)); + +/* + * Experimental extensions: + * + * elfx_movscn() moves section `__scn' directly after section `__after'. + * elfx_remscn() removes section `__scn'. Both functions update + * the section indices; elfx_remscn() also adjusts the ELF header's + * e_shnum member. The application is responsible for updating other + * data (in particular, e_shstrndx and the section headers' sh_link and + * sh_info members). + * + * elfx_movscn() returns the new index of the moved section. + * elfx_remscn() returns the original index of the removed section. + * A return value of zero indicates an error. + */ +extern size_t elfx_movscn __P((Elf *__elf, Elf_Scn *__scn, Elf_Scn *__after)); +extern size_t elfx_remscn __P((Elf *__elf, Elf_Scn *__scn)); + +/* + * elf_delscn() is obsolete. Please use elfx_remscn() instead. + */ +extern size_t elf_delscn __P((Elf *__elf, Elf_Scn *__scn)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LIBELF_H */ diff --git a/external/libelf/include/libelf/elf_repl.h b/external/libelf/include/libelf/elf_repl.h new file mode 100644 index 00000000..c5cf90f7 --- /dev/null +++ b/external/libelf/include/libelf/elf_repl.h @@ -0,0 +1,996 @@ +/* + * elf_repl.h - public header file for systems that lack it. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: elf_repl.h,v 1.22 2009/11/01 13:04:19 michael Exp $ */ + +/* + * NEVER INCLUDE THIS FILE DIRECTLY - USE INSTEAD! + */ + +#ifndef _ELF_REPL_H +#define _ELF_REPL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Scalar data types + */ +typedef __libelf_u32_t Elf32_Addr; +typedef __libelf_u16_t Elf32_Half; +typedef __libelf_u32_t Elf32_Off; +typedef __libelf_i32_t Elf32_Sword; +typedef __libelf_u32_t Elf32_Word; + +#define ELF32_FSZ_ADDR 4 +#define ELF32_FSZ_HALF 2 +#define ELF32_FSZ_OFF 4 +#define ELF32_FSZ_SWORD 4 +#define ELF32_FSZ_WORD 4 + +#if __LIBELF64 + +typedef __libelf_u64_t Elf64_Addr; +typedef __libelf_u16_t Elf64_Half; +typedef __libelf_u64_t Elf64_Off; +typedef __libelf_i32_t Elf64_Sword; +typedef __libelf_u32_t Elf64_Word; +typedef __libelf_i64_t Elf64_Sxword; +typedef __libelf_u64_t Elf64_Xword; + +#define ELF64_FSZ_ADDR 8 +#define ELF64_FSZ_HALF 2 +#define ELF64_FSZ_OFF 8 +#define ELF64_FSZ_SWORD 4 +#define ELF64_FSZ_WORD 4 +#define ELF64_FSZ_SXWORD 8 +#define ELF64_FSZ_XWORD 8 + +/* + * Blame Sun for this... + */ +typedef __libelf_u64_t Elf64_Lword; +typedef __libelf_u64_t Elf32_Lword; + +#endif /* __LIBELF64 */ + +/* + * ELF header + */ +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +#if __LIBELF64 +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; +#endif /* __LIBELF64 */ + +/* + * e_ident + */ +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +/* + * e_ident[EI_CLASS] + */ +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +/* + * e_ident[EI_DATA] + */ +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 +#define ELFDATANUM 3 + +/* + * e_ident[EI_OSABI] + */ +#define ELFOSABI_NONE 0 /* No extensions or unspecified */ +#define ELFOSABI_SYSV ELFOSABI_NONE +#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* Linux */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* Open BSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */ +#define ELFOSABI_AROS 15 /* Amiga Research OS */ +/* these are probably obsolete: */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */ + + +/* + * e_type + */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_NUM 5 +#define ET_LOOS 0xfe00 +#define ET_HIOS 0xfeff +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* + * e_machine + */ +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola 68000 */ +#define EM_88K 5 /* Motorola 88000 */ +#define EM_486 6 /* Intel i486 (DO NOT USE THIS ONE) */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS I Architecture */ +#define EM_S370 9 /* IBM System/370 Processor */ +#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */ +#define EM_SPARC64 11 /* SPARC 64-bit */ +#define EM_PARISC 15 /* Hewlett-Packard PA-RISC */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM System/390 Processor */ +#define EM_V800 36 /* NEC V800 */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* Advanced RISC Machines ARM */ +#define EM_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC Version 9 */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor */ +#define EM_ARC 45 /* Argonaut RISC Core, Argonaut Technologies Inc. */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel IA-64 processor architecture */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola ColdFire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Star*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor family */ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_AMD64 EM_X86_64 +#define EM_PDSP 63 /* Sony DSP Processor */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */ +#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */ +#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8-bit microcontroller */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */ +#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor */ +#define EM_NS32K 97 /* National Semiconductor 32000 series */ +#define EM_TPC 98 /* Tenor Network TPC processor */ +#define EM_SNP1K 99 /* Trebia SNP 1000 processor */ +#define EM_ST200 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */ +#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family */ +#define EM_MAX 102 /* MAX Processor */ +#define EM_CR 103 /* National Semiconductor CompactRISC microprocessor */ +#define EM_F2MC16 104 /* Fujitsu F2MC16 */ +#define EM_MSP430 105 /* Texas Instruments embedded microcontroller msp430 */ +#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor */ +#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */ +#define EM_SEP 108 /* Sharp embedded microprocessor */ +#define EM_ARCA 109 /* Arca RISC Microprocessor */ +#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ +#define EM_NUM 111 + +/* + * e_ident[EI_VERSION], e_version + */ +#define EV_NONE 0 +#define EV_CURRENT 1 +#define EV_NUM 2 + +/* + * Section header + */ +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +#if __LIBELF64 +typedef struct { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; +#endif /* __LIBELF64 */ + +/* + * Special section indices + */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_LOOS 0xff20 +#define SHN_HIOS 0xff3f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_XINDEX 0xffff +#define SHN_HIRESERVE 0xffff + +/* + * sh_type + */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_NUM 19 +#define SHT_LOOS 0x60000000 +#define SHT_HIOS 0x6fffffff +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* + * Solaris extensions + */ +#define SHT_LOSUNW 0x6ffffff4 +#define SHT_SUNW_dof 0x6ffffff4 +#define SHT_SUNW_cap 0x6ffffff5 +#define SHT_SUNW_SIGNATURE 0x6ffffff6 +#define SHT_SUNW_ANNOTATE 0x6ffffff7 +#define SHT_SUNW_DEBUGSTR 0x6ffffff8 +#define SHT_SUNW_DEBUG 0x6ffffff9 +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_SUNW_verdef 0x6ffffffd +#define SHT_SUNW_verneed 0x6ffffffe +#define SHT_SUNW_versym 0x6fffffff +#define SHT_HISUNW 0x6fffffff + +#define SHT_SPARC_GOTDATA 0x70000000 +#define SHT_AMD64_UNWIND 0x70000001 + +/* + * GNU extensions + */ +#define SHT_GNU_verdef 0x6ffffffd +#define SHT_GNU_verneed 0x6ffffffe +#define SHT_GNU_versym 0x6fffffff + +/* + * sh_flags + */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MERGE 0x10 +#define SHF_STRINGS 0x20 +#define SHF_INFO_LINK 0x40 +#define SHF_LINK_ORDER 0x80 +#define SHF_OS_NONCONFORMING 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xf0000000 + +/* + * Solaris extensions + */ +#define SHF_AMD64_LARGE 0x10000000 +#define SHF_ORDERED 0x40000000 +#define SHF_EXCLUDE 0x80000000 + +/* + * Section group flags + */ +#define GRP_COMDAT 0x1 +#define GRP_MASKOS 0x0ff00000 +#define GRP_MASKPROC 0xf0000000 + +/* + * Symbol table + */ +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +#if __LIBELF64 +typedef struct { + Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; +} Elf64_Sym; +#endif /* __LIBELF64 */ + +/* + * Special symbol indices + */ +#define STN_UNDEF 0 + +/* + * Macros for manipulating st_info + */ +#define ELF32_ST_BIND(i) ((i)>>4) +#define ELF32_ST_TYPE(i) ((i)&0xf) +#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +#if __LIBELF64 +#define ELF64_ST_BIND(i) ((i)>>4) +#define ELF64_ST_TYPE(i) ((i)&0xf) +#define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) +#endif /* __LIBELF64 */ + +/* + * Symbol binding + */ +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_NUM 3 +#define STB_LOOS 10 +#define STB_HIOS 12 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +/* + * Symbol types + */ +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 +#define STT_NUM 7 +#define STT_LOOS 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +/* + * Macros for manipulating st_other + */ +#define ELF32_ST_VISIBILITY(o) ((o)&0x3) +#if __LIBELF64 +#define ELF64_ST_VISIBILITY(o) ((o)&0x3) +#endif /* __LIBELF64 */ + +/* + * Symbol visibility + */ +#define STV_DEFAULT 0 +#define STV_INTERNAL 1 +#define STV_HIDDEN 2 +#define STV_PROTECTED 3 + +/* + * Relocation + */ +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +#if __LIBELF64 +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; +} Elf64_Rela; +#endif /* __LIBELF64 */ + +/* + * Macros for manipulating r_info + */ +#define ELF32_R_SYM(i) ((i)>>8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) + +#if __LIBELF64 +#define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32) +#define ELF64_R_TYPE(i) ((i)&0xffffffffL) +#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +#endif /* __LIBELF64 */ + +/* + * Note entry header + */ +typedef struct { + Elf32_Word n_namesz; /* name size */ + Elf32_Word n_descsz; /* descriptor size */ + Elf32_Word n_type; /* descriptor type */ +} Elf32_Nhdr; + +#if __LIBELF64 +/* Solaris and GNU use this layout. Be compatible. */ +/* XXX: Latest ELF specs say it's 64-bit!!! */ +typedef struct { + Elf64_Word n_namesz; /* name size */ + Elf64_Word n_descsz; /* descriptor size */ + Elf64_Word n_type; /* descriptor type */ +} Elf64_Nhdr; +#endif /* __LIBELF64 */ + +/* + * Well-known descriptor types for ET_CORE files + */ +#define NT_PRSTATUS 1 +#define NT_PRFPREG 2 +#define NT_PRPSINFO 3 + +/* + * Program header + */ +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +#if __LIBELF64 +typedef struct { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; +#endif /* __LIBELF64 */ + +/* + * Special numbers + */ +#define PN_XNUM 0xffff + +/* + * p_type + */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_NUM 8 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* + * Solaris extensions + */ + +#define PT_SUNW_UNWIND 0x6464e550 +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa +#define PT_SUNWSTACK 0x6ffffffb +#define PT_SUNWDTRACE 0x6ffffffc +#define PT_SUNWCAP 0x6ffffffd +#define PT_HISUNW 0x6fffffff + +/* + * p_flags + */ +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKOS 0x0ff00000 +#define PF_MASKPROC 0xf0000000 + +/* + * Dynamic structure + */ +typedef struct { + Elf32_Sword d_tag; + union { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +#if __LIBELF64 +typedef struct { + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; +#endif /* __LIBELF64 */ + +/* + * Dynamic array tags + */ + /* d_un exec shared */ +#define DT_NULL 0 /* ign. mand. mand. */ +#define DT_NEEDED 1 /* d_val opt. opt. */ +#define DT_PLTRELSZ 2 /* d_val opt. opt. */ +#define DT_PLTGOT 3 /* d_ptr opt. opt. */ +#define DT_HASH 4 /* d_ptr mand. mand. */ +#define DT_STRTAB 5 /* d_ptr mand. mand. */ +#define DT_SYMTAB 6 /* d_ptr mand. mand. */ +#define DT_RELA 7 /* d_ptr mand. opt. */ +#define DT_RELASZ 8 /* d_val mand. opt. */ +#define DT_RELAENT 9 /* d_val mand. opt. */ +#define DT_STRSZ 10 /* d_val mand. mand. */ +#define DT_SYMENT 11 /* d_val mand. mand. */ +#define DT_INIT 12 /* d_ptr opt. opt. */ +#define DT_FINI 13 /* d_ptr opt. opt. */ +#define DT_SONAME 14 /* d_val ign. opt. */ +#define DT_RPATH 15 /* d_val opt. ign. */ +#define DT_SYMBOLIC 16 /* ign. ign. opt. */ +#define DT_REL 17 /* d_ptr mand. opt. */ +#define DT_RELSZ 18 /* d_val mand. opt. */ +#define DT_RELENT 19 /* d_val mand. opt. */ +#define DT_PLTREL 20 /* d_val opt. opt. */ +#define DT_DEBUG 21 /* d_ptr opt. ign. */ +#define DT_TEXTREL 22 /* ign. opt. opt. */ +#define DT_JMPREL 23 /* d_ptr opt. opt. */ +#define DT_BIND_NOW 24 /* ign. opt. opt. */ +#define DT_INIT_ARRAY 25 /* d_ptr opt. opt. */ +#define DT_FINI_ARRAY 26 /* d_ptr opt. opt. */ +#define DT_INIT_ARRAYSZ 27 /* d_val opt. opt. */ +#define DT_FINI_ARRAYSZ 28 /* d_val opt. opt. */ +#define DT_RUNPATH 29 /* d_val opt. opt. */ +#define DT_FLAGS 30 /* d_val opt. opt. */ +#define DT_ENCODING 32 /* odd/even encoding rule starts here */ +#define DT_PREINIT_ARRAY 32 /* d_ptr opt. ign. */ +#define DT_PREINIT_ARRAYSZ 33 /* d_val opt. ign. */ +#define DT_NUM 34 +#define DT_LOOS 0x6000000D +#define DT_HIOS 0x6ffff000 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* + * DT_FLAGS values + */ +#define DF_ORIGIN 0x1 +#define DF_SYMBOLIC 0x2 +#define DF_TEXTREL 0x4 +#define DF_BIND_NOW 0x8 +#define DF_STATIC_TLS 0x10 + +/* + * Solaris extensions + */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc +#define DT_POSFLAG_1 0x6ffffdfd +#define DT_SYMINSZ 0x6ffffdfe +#define DT_SYMINENT 0x6ffffdff +#define DT_VALRNGHI 0x6ffffdff + +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_CONFIG 0x6ffffefa +#define DT_DEPAUDIT 0x6ffffefb +#define DT_AUDIT 0x6ffffefc +#define DT_PLTPAD 0x6ffffefd +#define DT_MOVETAB 0x6ffffefe +#define DT_SYMINFO 0x6ffffeff +#define DT_ADDRRNGHI 0x6ffffeff + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa +#define DT_FLAGS_1 0x6ffffffb +#define DT_VERDEF 0x6ffffffc +#define DT_VERDEFNUM 0x6ffffffd +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff + +#define DT_AUXILIARY 0x7ffffffd +#define DT_USED 0x7ffffffe +#define DT_FILTER 0x7fffffff + +/* + * GNU extensions + */ +#define DT_VERSYM 0x6ffffff0 + +/* + * DT_FEATURE_1 values + */ +#define DTF_1_PARINIT 0x1 +#define DTF_1_CONFEXP 0x2 + +/* + * DT_POSFLAG_1 values + */ +#define DF_P1_LAZYLOAD 0x1 +#define DF_P1_GROUPPERM 0x2 + +/* + * DT_FLAGS_1 values + */ +#define DF_1_NOW 0x00000001 +#define DF_1_GLOBAL 0x00000002 +#define DF_1_GROUP 0x00000004 +#define DF_1_NODELETE 0x00000008 +#define DF_1_LOADFLTR 0x00000010 +#define DF_1_INITFIRST 0x00000020 +#define DF_1_NOOPEN 0x00000040 +#define DF_1_ORIGIN 0x00000080 +#define DF_1_DIRECT 0x00000100 +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 +#define DF_1_NODEFLIB 0x00000800 +#define DF_1_NODUMP 0x00001000 +#define DF_1_CONFALT 0x00002000 +#define DF_1_ENDFILTEE 0x00004000 +#define DF_1_DISPRELDNE 0x00008000 +#define DF_1_DISPRELPND 0x00010000 + +/* + * Syminfo structure + */ +typedef struct { + Elf32_Half si_boundto; + Elf32_Half si_flags; +} Elf32_Syminfo; + +#if __LIBELF64 +typedef struct { + Elf64_Half si_boundto; + Elf64_Half si_flags; +} Elf64_Syminfo; +#endif /* __LIBELF64 */ + +/* + * Syminfo version (stored in unused first entry) + */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + +/* + * si_boundto special values + */ +#define SYMINFO_BT_LOWRESERVE 0xff00 +#define SYMINFO_BT_PARENT 0xfffe /* bound to parent */ +#define SYMINFO_BT_SELF 0xffff /* bound to self */ + +/* + * si_flags + */ +#define SYMINFO_FLG_DIRECT 0x01 /* bound to an object */ +#define SYMINFO_FLG_PASSTHRU 0x02 /* pass-thru symbol */ +#define SYMINFO_FLG_COPY 0x04 /* result of a copy relocation */ +#define SYMINFO_FLG_LAZYLOAD 0x08 /* bound to lazy-loaded object */ + +/* + * Version definitions + */ +typedef struct { + Elf32_Half vd_version; + Elf32_Half vd_flags; + Elf32_Half vd_ndx; + Elf32_Half vd_cnt; + Elf32_Word vd_hash; + Elf32_Word vd_aux; + Elf32_Word vd_next; +} Elf32_Verdef; + +typedef struct { + Elf32_Word vda_name; + Elf32_Word vda_next; +} Elf32_Verdaux; + +typedef struct { + Elf32_Half vn_version; + Elf32_Half vn_cnt; + Elf32_Word vn_file; + Elf32_Word vn_aux; + Elf32_Word vn_next; +} Elf32_Verneed; + +typedef struct { + Elf32_Word vna_hash; + Elf32_Half vna_flags; + Elf32_Half vna_other; + Elf32_Word vna_name; + Elf32_Word vna_next; +} Elf32_Vernaux; + +typedef Elf32_Half Elf32_Versym; + +#if __LIBELF64 + +typedef struct { + Elf64_Half vd_version; + Elf64_Half vd_flags; + Elf64_Half vd_ndx; + Elf64_Half vd_cnt; + Elf64_Word vd_hash; + Elf64_Word vd_aux; + Elf64_Word vd_next; +} Elf64_Verdef; + +typedef struct { + Elf64_Word vda_name; + Elf64_Word vda_next; +} Elf64_Verdaux; + +typedef struct { + Elf64_Half vn_version; + Elf64_Half vn_cnt; + Elf64_Word vn_file; + Elf64_Word vn_aux; + Elf64_Word vn_next; +} Elf64_Verneed; + +typedef struct { + Elf64_Word vna_hash; + Elf64_Half vna_flags; + Elf64_Half vna_other; + Elf64_Word vna_name; + Elf64_Word vna_next; +} Elf64_Vernaux; + +typedef Elf64_Half Elf64_Versym; + +#endif /* __LIBELF64 */ + +/* + * vd_version + */ +#define VER_DEF_NONE 0 +#define VER_DEF_CURRENT 1 +#define VER_DEF_NUM 2 + +/* + * vn_version + */ +#define VER_NEED_NONE 0 +#define VER_NEED_CURRENT 1 +#define VER_NEED_NUM 2 + +/* + * vd_flags / vna_flags + */ +#define VER_FLG_BASE 0x1 /* vd_flags only */ +#define VER_FLG_WEAK 0x2 + +/* + * Elf*_Versym special values + */ +#define VER_NDX_LOCAL 0 +#define VER_NDX_GLOBAL 1 + +/* + * Solaris extensions + */ + +/* + * Move section + */ +#if __LIBELF64 + +typedef struct { + Elf32_Lword m_value; + Elf32_Word m_info; + Elf32_Word m_poffset; + Elf32_Half m_repeat; + Elf32_Half m_stride; +} Elf32_Move; + +typedef struct { + Elf64_Lword m_value; + Elf64_Xword m_info; + Elf64_Xword m_poffset; + Elf64_Half m_repeat; + Elf64_Half m_stride; +} Elf64_Move; + +#define ELF32_M_SYM(info) ((info)>>8) +#define ELF32_M_SIZE(info) ((unsigned char)(info)) +#define ELF32_M_INFO(sym, sz) (((sym)<<8)+(unsigned char)(sz)) + +#define ELF64_M_SYM(info) ((Elf64_Xword)(info)>>8) +#define ELF64_M_SIZE(info) ((unsigned char)(info)) +#define ELF64_M_INFO(sym, sz) (((Elf64_Xword)(sym)<<8)+(unsigned char)(sz)) + +#endif /* __LIBELF64 */ + +/* + * Capabilities + */ + +typedef struct { + Elf32_Word c_tag; + union { + Elf32_Word c_val; + Elf32_Addr c_ptr; + } c_un; +} Elf32_Cap; + +#if __LIBELF64 + +typedef struct { + Elf64_Xword c_tag; + union { + Elf64_Xword c_val; + Elf64_Addr c_ptr; + } c_un; +} Elf64_Cap; + +#endif /* __LIBELF64 */ + +#define CA_SUNW_NULL 0 /* c_un ignored */ +#define CA_SUNW_HW_1 1 /* c_un.c_val */ +#define CA_SUNW_SF_1 2 /* c_un.c_val */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ELF_REPL_H */ diff --git a/external/libelf/include/libelf/sys_elf.h b/external/libelf/include/libelf/sys_elf.h new file mode 100644 index 00000000..70506c31 --- /dev/null +++ b/external/libelf/include/libelf/sys_elf.h @@ -0,0 +1,130 @@ +/* + * lib/sys_elf.h.w32 - internal configuration file for W32 port + * Copyright (C) 2004 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @(#) $Id: sys_elf.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $ + */ + +/* + * DO NOT USE THIS IN APPLICATIONS - #include INSTEAD! + */ + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define if you want 64-bit support (and your system supports it) */ +#define __LIBELF64 1 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#define __LIBELF_SYMBOL_VERSIONS 1 + +/* Define to a 64-bit signed integer type if one exists */ +#define __libelf_i64_t __int64 + +/* Define to a 64-bit unsigned integer type if one exists */ +#define __libelf_u64_t unsigned __int64 + +/* Define to a 32-bit signed integer type if one exists */ +#define __libelf_i32_t int + +/* Define to a 32-bit unsigned integer type if one exists */ +#define __libelf_u32_t unsigned int + +/* Define to a 16-bit signed integer type if one exists */ +#define __libelf_i16_t short int + +/* Define to a 16-bit unsigned integer type if one exists */ +#define __libelf_u16_t unsigned short int + +/* + * Ok, now get the correct instance of elf.h... + */ +#ifdef __LIBELF_HEADER_ELF_H +# include __LIBELF_HEADER_ELF_H +#else /* __LIBELF_HEADER_ELF_H */ +# if __LIBELF_INTERNAL__ +# include +# else /* __LIBELF_INTERNAL__ */ +# include +# endif /* __LIBELF_INTERNAL__ */ +#endif /* __LIBELF_HEADER_ELF_H */ + +/* + * On some systems, is severely broken. Try to fix it. + */ +#ifdef __LIBELF_HEADER_ELF_H + +# ifndef ELF32_FSZ_ADDR +# define ELF32_FSZ_ADDR 4 +# define ELF32_FSZ_HALF 2 +# define ELF32_FSZ_OFF 4 +# define ELF32_FSZ_SWORD 4 +# define ELF32_FSZ_WORD 4 +# endif /* ELF32_FSZ_ADDR */ + +# ifndef STN_UNDEF +# define STN_UNDEF 0 +# endif /* STN_UNDEF */ + +# if __LIBELF64 + +# ifndef ELF64_FSZ_ADDR +# define ELF64_FSZ_ADDR 8 +# define ELF64_FSZ_HALF 2 +# define ELF64_FSZ_OFF 8 +# define ELF64_FSZ_SWORD 4 +# define ELF64_FSZ_WORD 4 +# define ELF64_FSZ_SXWORD 8 +# define ELF64_FSZ_XWORD 8 +# endif /* ELF64_FSZ_ADDR */ + +# ifndef ELF64_ST_BIND +# define ELF64_ST_BIND(i) ((i)>>4) +# define ELF64_ST_TYPE(i) ((i)&0xf) +# define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) +# endif /* ELF64_ST_BIND */ + +# ifndef ELF64_R_SYM +# define ELF64_R_SYM(i) ((Elf64_Xword)(i)>>32) +# define ELF64_R_TYPE(i) ((i)&0xffffffffL) +# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +# endif /* ELF64_R_SYM */ + +# if __LIBELF64_LINUX +typedef __libelf_u64_t Elf64_Addr; +typedef __libelf_u16_t Elf64_Half; +typedef __libelf_u64_t Elf64_Off; +typedef __libelf_i32_t Elf64_Sword; +typedef __libelf_u32_t Elf64_Word; +typedef __libelf_i64_t Elf64_Sxword; +typedef __libelf_u64_t Elf64_Xword; +# endif /* __LIBELF64_LINUX */ + +# endif /* __LIBELF64 */ +#endif /* __LIBELF_HEADER_ELF_H */ diff --git a/external/libelf/libelf.vcxproj b/external/libelf/libelf.vcxproj new file mode 100644 index 00000000..95285e8a --- /dev/null +++ b/external/libelf/libelf.vcxproj @@ -0,0 +1,222 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16.0 + Win32Proj + {a2d07885-a0d1-473b-83b2-209cd008ee8f} + libelf + 10.0 + libelf + + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + include;include\libelf;src + 4244;4267;4311 + + + true + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include;include\libelf;src + 4244;4267;4311 + + + true + true + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_CONFIG_H=1;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + include;include\libelf;src + 4244;4267;4311 + + + true + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_CONFIG_H=1;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include;include\libelf;src + 4244;4267;4311 + + + true + true + true + + + + + + \ No newline at end of file diff --git a/external/libelf/libelf.vcxproj.filters b/external/libelf/libelf.vcxproj.filters new file mode 100644 index 00000000..66ebd9d9 --- /dev/null +++ b/external/libelf/libelf.vcxproj.filters @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/libelf/src/32.fsize.c b/external/libelf/src/32.fsize.c new file mode 100644 index 00000000..1815fa10 --- /dev/null +++ b/external/libelf/src/32.fsize.c @@ -0,0 +1,155 @@ +/* +32.fsize.c - implementation of the elf{32,64}_fsize(3) functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.fsize.c,v 1.13 2008/05/23 08:15:33 michael Exp $"; +#endif /* lint */ + +const size_t +_elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2] = { + /* ELFCLASS32 */ + { + /* version 1 */ + { + { sizeof(unsigned char), sizeof(unsigned char) }, + { sizeof(Elf32_Addr), sizeof(__ext_Elf32_Addr) }, + { sizeof(Elf32_Dyn), sizeof(__ext_Elf32_Dyn) }, + { sizeof(Elf32_Ehdr), sizeof(__ext_Elf32_Ehdr) }, + { sizeof(Elf32_Half), sizeof(__ext_Elf32_Half) }, + { sizeof(Elf32_Off), sizeof(__ext_Elf32_Off) }, + { sizeof(Elf32_Phdr), sizeof(__ext_Elf32_Phdr) }, + { sizeof(Elf32_Rela), sizeof(__ext_Elf32_Rela) }, + { sizeof(Elf32_Rel), sizeof(__ext_Elf32_Rel) }, + { sizeof(Elf32_Shdr), sizeof(__ext_Elf32_Shdr) }, + { sizeof(Elf32_Sword), sizeof(__ext_Elf32_Sword) }, + { sizeof(Elf32_Sym), sizeof(__ext_Elf32_Sym) }, + { sizeof(Elf32_Word), sizeof(__ext_Elf32_Word) }, + { 0, 0 }, /* there is no Elf32_Sxword */ + { 0, 0 }, /* there is no Elf32_Xword */ + /* XXX: check Solaris values */ + { 0, 0 }, /* Elf32_Verdef/Verdaux size varies */ + { 0, 0 }, /* Elf32_Verneed/Vernaux size varies */ + }, + }, +#if __LIBELF64 + /* ELFCLASS64 */ + { + /* version 1 */ + { + { sizeof(unsigned char), sizeof(unsigned char) }, + { sizeof(Elf64_Addr), sizeof(__ext_Elf64_Addr) }, + { sizeof(Elf64_Dyn), sizeof(__ext_Elf64_Dyn) }, + { sizeof(Elf64_Ehdr), sizeof(__ext_Elf64_Ehdr) }, + { sizeof(Elf64_Half), sizeof(__ext_Elf64_Half) }, + { sizeof(Elf64_Off), sizeof(__ext_Elf64_Off) }, + { sizeof(Elf64_Phdr), sizeof(__ext_Elf64_Phdr) }, + { sizeof(Elf64_Rela), sizeof(__ext_Elf64_Rela) }, + { sizeof(Elf64_Rel), sizeof(__ext_Elf64_Rel) }, + { sizeof(Elf64_Shdr), sizeof(__ext_Elf64_Shdr) }, + { sizeof(Elf64_Sword), sizeof(__ext_Elf64_Sword) }, + { sizeof(Elf64_Sym), sizeof(__ext_Elf64_Sym) }, + { sizeof(Elf64_Word), sizeof(__ext_Elf64_Word) }, + { sizeof(Elf64_Sxword), sizeof(__ext_Elf64_Sxword) }, + { sizeof(Elf64_Xword), sizeof(__ext_Elf64_Xword) }, + /* XXX: check Solaris values */ + { 0, 0 }, /* Elf64_Verdef/Verdaux size varies */ + { 0, 0 }, /* Elf64_Verneed/Vernaux size varies */ + }, + }, +#endif /* __LIBELF64 */ +}; + +static size_t +_elf_fsize(unsigned cls, Elf_Type type, unsigned ver) { + size_t n = 0; + + if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + } + else if (!(n = _fsize(cls, ver, type))) { + seterr(ERROR_UNKNOWN_TYPE); + } + return n; +} + +size_t +elf32_fsize(Elf_Type type, size_t count, unsigned ver) { + return count * _elf_fsize(ELFCLASS32, type, ver); +} + +#if __LIBELF64 + +size_t +elf64_fsize(Elf_Type type, size_t count, unsigned ver) { + return count * _elf_fsize(ELFCLASS64, type, ver); +} + +size_t +gelf_fsize(Elf *elf, Elf_Type type, size_t count, unsigned ver) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (valid_class(elf->e_class)) { + return count * _elf_fsize(elf->e_class, type, ver); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return 0; +} + +/* + * Extension: report memory size + */ +size_t +gelf_msize(Elf *elf, Elf_Type type, size_t count, unsigned ver) { + size_t n; + + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + } + else if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + } + else if (!(n = _msize(elf->e_class, ver, type))) { + seterr(ERROR_UNKNOWN_TYPE); + } + else { + return count * n; + } + } + return 0; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.getehdr.c b/external/libelf/src/32.getehdr.c new file mode 100644 index 00000000..5690dd06 --- /dev/null +++ b/external/libelf/src/32.getehdr.c @@ -0,0 +1,56 @@ +/* +32.getehdr.c - implementation of the elf{32,64}_getehdr(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getehdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +char* +_elf_getehdr(Elf *elf, unsigned cls) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + return elf->e_ehdr; + } + return NULL; +} + +Elf32_Ehdr* +elf32_getehdr(Elf *elf) { + return (Elf32_Ehdr*)_elf_getehdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Ehdr* +elf64_getehdr(Elf *elf) { + return (Elf64_Ehdr*)_elf_getehdr(elf, ELFCLASS64); +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.getphdr.c b/external/libelf/src/32.getphdr.c new file mode 100644 index 00000000..c34b8c76 --- /dev/null +++ b/external/libelf/src/32.getphdr.c @@ -0,0 +1,56 @@ +/* +32.getphdr.c - implementation of the elf{32,64}_getphdr(3) functions. +Copyright (C) 1995 - 2000 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getphdr.c,v 1.11 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +char* +_elf_getphdr(Elf *elf, unsigned cls) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + return elf->e_phdr; + } + return NULL; +} + +Elf32_Phdr* +elf32_getphdr(Elf *elf) { + return (Elf32_Phdr*)_elf_getphdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Phdr* +elf64_getphdr(Elf *elf) { + return (Elf64_Phdr*)_elf_getphdr(elf, ELFCLASS64); +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.getshdr.c b/external/libelf/src/32.getshdr.c new file mode 100644 index 00000000..498cc5aa --- /dev/null +++ b/external/libelf/src/32.getshdr.c @@ -0,0 +1,58 @@ +/* +32.getshdr.c - implementation of the elf{32,64}_getshdr(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.getshdr.c,v 1.10 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +Elf32_Shdr* +elf32_getshdr(Elf_Scn *scn) { + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS32) { + return &scn->s_shdr32; + } + seterr(ERROR_CLASSMISMATCH); + return NULL; +} + +#if __LIBELF64 + +Elf64_Shdr* +elf64_getshdr(Elf_Scn *scn) { + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS64) { + return &scn->s_shdr64; + } + seterr(ERROR_CLASSMISMATCH); + return NULL; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.newehdr.c b/external/libelf/src/32.newehdr.c new file mode 100644 index 00000000..fd59fb76 --- /dev/null +++ b/external/libelf/src/32.newehdr.c @@ -0,0 +1,80 @@ +/* + * 32.newehdr.c - implementation of the elf{32,64}_newehdr(3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.newehdr.c,v 1.16 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +static char* +_elf_newehdr(Elf *elf, unsigned cls) { + size_t size; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_readable) { + return _elf_getehdr(elf, cls); + } + else if (!elf->e_ehdr) { + size = _msize(cls, _elf_version, ELF_T_EHDR); + elf_assert(size); + if ((elf->e_ehdr = (char*)malloc(size))) { + memset(elf->e_ehdr, 0, size); + elf->e_ehdr_flags |= ELF_F_DIRTY; + elf->e_kind = ELF_K_ELF; + elf->e_class = cls; + return elf->e_ehdr; + } + seterr(ERROR_MEM_EHDR); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else { + elf_assert(elf->e_kind == ELF_K_ELF); + return elf->e_ehdr; + } + return NULL; +} + +Elf32_Ehdr* +elf32_newehdr(Elf *elf) { + return (Elf32_Ehdr*)_elf_newehdr(elf, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Ehdr* +elf64_newehdr(Elf *elf) { + return (Elf64_Ehdr*)_elf_newehdr(elf, ELFCLASS64); +} + +unsigned long +gelf_newehdr(Elf *elf, int cls) { + if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) { + seterr(ERROR_UNKNOWN_CLASS); + return 0; + } + return (unsigned long)_elf_newehdr(elf, cls); +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.newphdr.c b/external/libelf/src/32.newphdr.c new file mode 100644 index 00000000..91c63df2 --- /dev/null +++ b/external/libelf/src/32.newphdr.c @@ -0,0 +1,118 @@ +/* + * 32.newphdr.c - implementation of the elf{32,64}_newphdr(3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.newphdr.c,v 1.16 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +static char* +_elf_newphdr(Elf *elf, size_t count, unsigned cls) { + size_t extcount = 0; + Elf_Scn *scn = NULL; + char *phdr = NULL; + size_t size; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_ehdr && !elf->e_readable) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != cls) { + seterr(ERROR_CLASSMISMATCH); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + size = _msize(cls, _elf_version, ELF_T_PHDR); + elf_assert(size); + if (!(scn = _elf_first_scn(elf))) { + return NULL; + } + if (count) { + if (!(phdr = (char*)malloc(count * size))) { + seterr(ERROR_MEM_PHDR); + return NULL; + } + memset(phdr, 0, count * size); + } + elf_assert(elf->e_ehdr); + elf->e_phnum = count; + if (count >= PN_XNUM) { + /* + * get NULL section (create it if necessary) + */ + extcount = count; + count = PN_XNUM; + } + if (cls == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum = count; + scn->s_shdr32.sh_info = extcount; + } +#if __LIBELF64 + else if (cls == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum = count; + scn->s_shdr64.sh_info = extcount; + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + if (phdr) { + free(phdr); + } + return NULL; + } + if (elf->e_phdr) { + free(elf->e_phdr); + } + elf->e_phdr = phdr; + elf->e_phdr_flags |= ELF_F_DIRTY; + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_scn_flags |= ELF_F_DIRTY; + return phdr; + } + return NULL; +} + +Elf32_Phdr* +elf32_newphdr(Elf *elf, size_t count) { + return (Elf32_Phdr*)_elf_newphdr(elf, count, ELFCLASS32); +} + +#if __LIBELF64 + +Elf64_Phdr* +elf64_newphdr(Elf *elf, size_t count) { + return (Elf64_Phdr*)_elf_newphdr(elf, count, ELFCLASS64); +} + +unsigned long +gelf_newphdr(Elf *elf, size_t phnum) { + if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + return 0; + } + return (unsigned long)_elf_newphdr(elf, phnum, elf->e_class); +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/32.xlatetof.c b/external/libelf/src/32.xlatetof.c new file mode 100644 index 00000000..068bac53 --- /dev/null +++ b/external/libelf/src/32.xlatetof.c @@ -0,0 +1,438 @@ +/* + * 32.xlatetof.c - implementation of the elf32_xlateto[fm](3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 32.xlatetof.c,v 1.27 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +/* + * Ugly, ugly + */ +#ifdef _WIN32 +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +#else /* _WIN32 */ +# define x +# if defined/**/x +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +# else +# define Cat2(a,b)a/**/b +# define Cat3(a,b,c)a/**/b/**/c +# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b) +# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c) +# endif +# undef x +#endif /* _WIN32 */ + +/* + * auxiliary macros for execution order reversal + */ +#define seq_forw(a,b) a b +#define seq_back(a,b) b a + +/* + * function instantiator + */ +#define copy_type_e_io(name,e,io,tfrom,tto,copy) \ + static size_t \ + Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \ + n /= sizeof(tfrom); \ + if (n && dst) { \ + const tfrom *from = (const tfrom*)src; \ + tto *to = (tto*)dst; \ + size_t i; \ + \ + if (sizeof(tfrom) < sizeof(tto)) { \ + from += n; \ + to += n; \ + for (i = 0; i < n; i++) { \ + --from; \ + --to; \ + copy(e,io,seq_back) \ + } \ + } \ + else { \ + for (i = 0; i < n; i++) { \ + copy(e,io,seq_forw) \ + from++; \ + to++; \ + } \ + } \ + } \ + return n * sizeof(tto); \ + } + +#define copy_type_e(name,e,type,copy) \ + copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \ + copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy) + +/* + * master function instantiator + */ +#define copy_type(name,version,type,copy) \ + copy_type_e(Cat3(name,L,version),L,type,copy) \ + copy_type_e(Cat3(name,M,version),M,type,copy) + +/* + * scalar copying + */ +#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from); +#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from); + +/* + * structure member copying + */ +#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb); +#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb); + +/* + * structure member copying (direction independent) + */ +#define copy_byte(e,io,mb) to->mb = from->mb; +#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e) +#define copy_off(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e) +#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_arr(e,io,mb) \ + array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb)); + +/* + * scalar copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e) +#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e) +#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) + +/* + * structure copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_dyn_11(e,io,seq) \ + seq(copy_sword(e,io,d_tag), \ + seq(copy_addr(e,io,d_un.d_ptr), \ + nullcopy)) +#define copy_ehdr_11(e,io,seq) \ + seq(copy_arr(e,io,e_ident), \ + seq(copy_half(e,io,e_type), \ + seq(copy_half(e,io,e_machine), \ + seq(copy_word(e,io,e_version), \ + seq(copy_addr(e,io,e_entry), \ + seq(copy_off(e,io,e_phoff), \ + seq(copy_off(e,io,e_shoff), \ + seq(copy_word(e,io,e_flags), \ + seq(copy_half(e,io,e_ehsize), \ + seq(copy_half(e,io,e_phentsize), \ + seq(copy_half(e,io,e_phnum), \ + seq(copy_half(e,io,e_shentsize), \ + seq(copy_half(e,io,e_shnum), \ + seq(copy_half(e,io,e_shstrndx), \ + nullcopy)))))))))))))) +#define copy_phdr_11(e,io,seq) \ + seq(copy_word(e,io,p_type), \ + seq(copy_off(e,io,p_offset), \ + seq(copy_addr(e,io,p_vaddr), \ + seq(copy_addr(e,io,p_paddr), \ + seq(copy_word(e,io,p_filesz), \ + seq(copy_word(e,io,p_memsz), \ + seq(copy_word(e,io,p_flags), \ + seq(copy_word(e,io,p_align), \ + nullcopy)))))))) +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_info), \ + seq(copy_sword(e,io,r_addend), \ + nullcopy))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_info), \ + nullcopy)) +#define copy_shdr_11(e,io,seq) \ + seq(copy_word(e,io,sh_name), \ + seq(copy_word(e,io,sh_type), \ + seq(copy_word(e,io,sh_flags), \ + seq(copy_addr(e,io,sh_addr), \ + seq(copy_off(e,io,sh_offset), \ + seq(copy_word(e,io,sh_size), \ + seq(copy_word(e,io,sh_link), \ + seq(copy_word(e,io,sh_info), \ + seq(copy_word(e,io,sh_addralign), \ + seq(copy_word(e,io,sh_entsize), \ + nullcopy)))))))))) +#define copy_sym_11(e,io,seq) \ + seq(copy_word(e,io,st_name), \ + seq(copy_addr(e,io,st_value), \ + seq(copy_word(e,io,st_size), \ + seq(copy_byte(e,io,st_info), \ + seq(copy_byte(e,io,st_other), \ + seq(copy_half(e,io,st_shndx), \ + nullcopy)))))) + +#define nullcopy /**/ + +static size_t +byte_copy(unsigned char *dst, const unsigned char *src, size_t n) { + if (n && dst && dst != src) { +#if HAVE_BROKEN_MEMMOVE + size_t i; + + if (dst >= src + n || dst + n <= src) { + memcpy(dst, src, n); + } + else if (dst < src) { + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } + } + else { + for (i = n; --i; ) { + dst[i] = src[i]; + } + } +#else /* HAVE_BROKEN_MEMMOVE */ + memmove(dst, src, n); +#endif /* HAVE_BROKEN_MEMMOVE */ + } + return n; +} + +static void +array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { + byte_copy(dst, src, dlen < slen ? dlen : slen); + if (dlen > slen) { + memset(dst + slen, 0, dlen - slen); + } +} + +/* + * instantiate copy functions + */ +copy_type(addr_32,_,Elf32_Addr,copy_addr_11) +copy_type(half_32,_,Elf32_Half,copy_half_11) +copy_type(off_32,_,Elf32_Off,copy_off_11) +copy_type(sword_32,_,Elf32_Sword,copy_sword_11) +copy_type(word_32,_,Elf32_Word,copy_word_11) +copy_type(dyn_32,11,Elf32_Dyn,copy_dyn_11) +copy_type(ehdr_32,11,Elf32_Ehdr,copy_ehdr_11) +copy_type(phdr_32,11,Elf32_Phdr,copy_phdr_11) +copy_type(rela_32,11,Elf32_Rela,copy_rela_11) +copy_type(rel_32,11,Elf32_Rel,copy_rel_11) +copy_type(shdr_32,11,Elf32_Shdr,copy_shdr_11) +copy_type(sym_32,11,Elf32_Sym,copy_sym_11) + +typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t); +typedef xlator xltab[ELF_T_NUM][2]; + +/* + * translation table (32-bit, version 1 -> version 1) + */ +#if PIC +static xltab +#else /* PIC */ +static const xltab +#endif /* PIC */ +xlate32_11[/*encoding*/] = { + { + { byte_copy, byte_copy }, + { addr_32L__tom, addr_32L__tof }, + { dyn_32L11_tom, dyn_32L11_tof }, + { ehdr_32L11_tom, ehdr_32L11_tof }, + { half_32L__tom, half_32L__tof }, + { off_32L__tom, off_32L__tof }, + { phdr_32L11_tom, phdr_32L11_tof }, + { rela_32L11_tom, rela_32L11_tof }, + { rel_32L11_tom, rel_32L11_tof }, + { shdr_32L11_tom, shdr_32L11_tof }, + { sword_32L__tom, sword_32L__tof }, + { sym_32L11_tom, sym_32L11_tof }, + { word_32L__tom, word_32L__tof }, + { 0, 0 }, /* there is no Sxword */ + { 0, 0 }, /* there is no Xword */ +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_32L11_tom, _elf_verdef_32L11_tof }, + { _elf_verneed_32L11_tom, _elf_verneed_32L11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, + { + { byte_copy, byte_copy }, + { addr_32M__tom, addr_32M__tof }, + { dyn_32M11_tom, dyn_32M11_tof }, + { ehdr_32M11_tom, ehdr_32M11_tof }, + { half_32M__tom, half_32M__tof }, + { off_32M__tom, off_32M__tof }, + { phdr_32M11_tom, phdr_32M11_tof }, + { rela_32M11_tom, rela_32M11_tof }, + { rel_32M11_tom, rel_32M11_tof }, + { shdr_32M11_tom, shdr_32M11_tof }, + { sword_32M__tom, sword_32M__tof }, + { sym_32M11_tom, sym_32M11_tof }, + { word_32M__tom, word_32M__tof }, + { 0, 0 }, /* there is no Sxword */ + { 0, 0 }, /* there is no Xword */ +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_32M11_tom, _elf_verdef_32M11_tof }, + { _elf_verneed_32M11_tom, _elf_verneed_32M11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, +}; + +/* + * main translation table (32-bit) + */ +#if PIC +static xltab* +#else /* PIC */ +static const xltab *const +#endif /* PIC */ +xlate32[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = { + { xlate32_11, }, +}; + +#define translator(sv,dv,enc,type,d) \ + (xlate32[(sv) - EV_NONE - 1] \ + [(dv) - EV_NONE - 1] \ + [(enc) - ELFDATA2LSB] \ + [(type) - ELF_T_BYTE] \ + [d]) + +/* + * destination buffer size + */ +size_t +_elf32_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) { + Elf_Type type = src->d_type; + unsigned sv = src->d_version; + xlator op; + + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return (size_t)-1; + } + if (tof) { + /* + * Encoding doesn't really matter (the translator only looks at + * the source, which resides in memory), but we need a proper + * encoding to select a translator... + */ + encode = ELFDATA2LSB; + } + else if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return (size_t)-1; + } + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + if (!(op = translator(sv, dv, encode, type, tof))) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + return (*op)(NULL, src->d_buf, src->d_size); +} + +/* + * direction-independent translation + */ +static Elf_Data* +elf32_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) { + Elf_Type type; + int dv; + int sv; + size_t dsize; + size_t tmp; + xlator op; + + if (!src || !dst) { + return NULL; + } + if (!src->d_buf || !dst->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return NULL; + } + sv = src->d_version; + dv = dst->d_version; + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return NULL; + } + type = src->d_type; + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + op = translator(sv, dv, encode, type, tof); + if (!op) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + dsize = (*op)(NULL, src->d_buf, src->d_size); + if (dsize == (size_t)-1) { + return NULL; + } + if (dst->d_size < dsize) { + seterr(ERROR_DST2SMALL); + return NULL; + } + if (dsize) { + tmp = (*op)(dst->d_buf, src->d_buf, src->d_size); + if (tmp == (size_t)-1) { + return NULL; + } + elf_assert(tmp == dsize); + } + dst->d_size = dsize; + dst->d_type = type; + return dst; +} + +/* + * finally, the "official" translation functions + */ +Elf_Data* +elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf32_xlate(dst, src, encode, 0); +} + +Elf_Data* +elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf32_xlate(dst, src, encode, 1); +} diff --git a/external/libelf/src/64.xlatetof.c b/external/libelf/src/64.xlatetof.c new file mode 100644 index 00000000..c66f0008 --- /dev/null +++ b/external/libelf/src/64.xlatetof.c @@ -0,0 +1,512 @@ +/* + * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.27 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +/* + * Ugly, ugly + */ +#ifdef _WIN32 +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +#else /* _WIN32 */ +# define x +# if defined/**/x +# define Cat2(a,b)a##b +# define Cat3(a,b,c)a##b##c +# define Ex1(m1,m2,a,b)m1##m2(a##b) +# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) +# else +# define Cat2(a,b)a/**/b +# define Cat3(a,b,c)a/**/b/**/c +# define Ex1(m1,m2,a,b)m1/**/m2(a/**/b) +# define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c) +# endif +# undef x +#endif /* _WIN32 */ + +/* + * auxiliary macros for execution order reversal + */ +#define seq_forw(a,b) a b +#define seq_back(a,b) b a + +/* + * function instantiator + */ +#define copy_type_e_io(name,e,io,tfrom,tto,copy) \ + static size_t \ + Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \ + n /= sizeof(tfrom); \ + if (n && dst) { \ + const tfrom *from = (const tfrom*)src; \ + tto *to = (tto*)dst; \ + size_t i; \ + \ + if (sizeof(tfrom) < sizeof(tto)) { \ + from += n; \ + to += n; \ + for (i = 0; i < n; i++) { \ + --from; \ + --to; \ + copy(e,io,seq_back) \ + } \ + } \ + else { \ + for (i = 0; i < n; i++) { \ + copy(e,io,seq_forw) \ + from++; \ + to++; \ + } \ + } \ + } \ + return n * sizeof(tto); \ + } + +#define copy_type_e(name,e,type,copy) \ + copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \ + copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy) + +/* + * master function instantiator + */ +#define copy_type(name,version,type,copy) \ + copy_type_e(Cat3(name,L,version),L,type,copy) \ + copy_type_e(Cat3(name,M,version),M,type,copy) + +/* + * scalar copying + */ +#define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from); +#define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from); + +/* + * structure member copying + */ +#define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb); +#define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb); + +/* + * structure member copying (direction independent) + */ +#define copy_byte(e,io,mb) to->mb = from->mb; +#define copy_addr(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e) +#define copy_off(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e) +#define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e) +#define copy_sxword(e,io,mb) Ex2(copy_,io,mb,i64,e) +#define copy_xword(e,io,mb) Ex2(copy_,io,mb,u64,e) +#define copy_arr(e,io,mb) \ + array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb)); + +/* + * scalar copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) +#define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e) +#define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) +#define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e) +#define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) +#define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e) +#define copy_xword_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) + +/* + * structure copying (direction independent) + * these macros are used as `copy' arguments to copy_type() + */ +#define copy_dyn_11(e,io,seq) \ + seq(copy_xword(e,io,d_tag), \ + seq(copy_addr(e,io,d_un.d_ptr), \ + nullcopy)) +#define copy_ehdr_11(e,io,seq) \ + seq(copy_arr(e,io,e_ident), \ + seq(copy_half(e,io,e_type), \ + seq(copy_half(e,io,e_machine), \ + seq(copy_word(e,io,e_version), \ + seq(copy_addr(e,io,e_entry), \ + seq(copy_off(e,io,e_phoff), \ + seq(copy_off(e,io,e_shoff), \ + seq(copy_word(e,io,e_flags), \ + seq(copy_half(e,io,e_ehsize), \ + seq(copy_half(e,io,e_phentsize), \ + seq(copy_half(e,io,e_phnum), \ + seq(copy_half(e,io,e_shentsize), \ + seq(copy_half(e,io,e_shnum), \ + seq(copy_half(e,io,e_shstrndx), \ + nullcopy)))))))))))))) +#define copy_phdr_11(e,io,seq) \ + seq(copy_word(e,io,p_type), \ + seq(copy_word(e,io,p_flags), \ + seq(copy_off(e,io,p_offset), \ + seq(copy_addr(e,io,p_vaddr), \ + seq(copy_addr(e,io,p_paddr), \ + seq(copy_xword(e,io,p_filesz), \ + seq(copy_xword(e,io,p_memsz), \ + seq(copy_xword(e,io,p_align), \ + nullcopy)))))))) +#if __LIBELF64_IRIX +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_sym), \ + seq(copy_byte(e,io,r_ssym), \ + seq(copy_byte(e,io,r_type3), \ + seq(copy_byte(e,io,r_type2), \ + seq(copy_byte(e,io,r_type), \ + seq(copy_sxword(e,io,r_addend), \ + nullcopy))))))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_word(e,io,r_sym), \ + seq(copy_byte(e,io,r_ssym), \ + seq(copy_byte(e,io,r_type3), \ + seq(copy_byte(e,io,r_type2), \ + seq(copy_byte(e,io,r_type), \ + nullcopy)))))) +#else /* __LIBELF64_IRIX */ +#define copy_rela_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_xword(e,io,r_info), \ + seq(copy_sxword(e,io,r_addend), \ + nullcopy))) +#define copy_rel_11(e,io,seq) \ + seq(copy_addr(e,io,r_offset), \ + seq(copy_xword(e,io,r_info), \ + nullcopy)) +#endif /* __LIBELF64_IRIX */ +#define copy_shdr_11(e,io,seq) \ + seq(copy_word(e,io,sh_name), \ + seq(copy_word(e,io,sh_type), \ + seq(copy_xword(e,io,sh_flags), \ + seq(copy_addr(e,io,sh_addr), \ + seq(copy_off(e,io,sh_offset), \ + seq(copy_xword(e,io,sh_size), \ + seq(copy_word(e,io,sh_link), \ + seq(copy_word(e,io,sh_info), \ + seq(copy_xword(e,io,sh_addralign), \ + seq(copy_xword(e,io,sh_entsize), \ + nullcopy)))))))))) +#define copy_sym_11(e,io,seq) \ + seq(copy_word(e,io,st_name), \ + seq(copy_byte(e,io,st_info), \ + seq(copy_byte(e,io,st_other), \ + seq(copy_half(e,io,st_shndx), \ + seq(copy_addr(e,io,st_value), \ + seq(copy_xword(e,io,st_size), \ + nullcopy)))))) + +#define nullcopy /**/ + +static size_t +byte_copy(unsigned char *dst, const unsigned char *src, size_t n) { + if (n && dst && dst != src) { +#if HAVE_BROKEN_MEMMOVE + size_t i; + + if (dst >= src + n || dst + n <= src) { + memcpy(dst, src, n); + } + else if (dst < src) { + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } + } + else { + for (i = n; --i; ) { + dst[i] = src[i]; + } + } +#else /* HAVE_BROKEN_MEMMOVE */ + memmove(dst, src, n); +#endif /* HAVE_BROKEN_MEMMOVE */ + } + return n; +} + +static void +array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { + byte_copy(dst, src, dlen < slen ? dlen : slen); + if (dlen > slen) { + memset(dst + slen, 0, dlen - slen); + } +} + +/* + * instantiate copy functions + */ +copy_type(addr_64,_,Elf64_Addr,copy_addr_11) +copy_type(half_64,_,Elf64_Half,copy_half_11) +copy_type(off_64,_,Elf64_Off,copy_off_11) +copy_type(sword_64,_,Elf64_Sword,copy_sword_11) +copy_type(word_64,_,Elf64_Word,copy_word_11) +copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11) +copy_type(xword_64,_,Elf64_Xword,copy_xword_11) +copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11) +copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11) +copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11) +copy_type(rela_64,11,Elf64_Rela,copy_rela_11) +copy_type(rel_64,11,Elf64_Rel,copy_rel_11) +copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11) +copy_type(sym_64,11,Elf64_Sym,copy_sym_11) + +typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t); +typedef xlator xltab[ELF_T_NUM][2]; + +/* + * translation table (64-bit, version 1 -> version 1) + */ +#if PIC +static xltab +#else /* PIC */ +static const xltab +#endif /* PIC */ +xlate64_11[/*encoding*/] = { + { + { byte_copy, byte_copy }, + { addr_64L__tom, addr_64L__tof }, + { dyn_64L11_tom, dyn_64L11_tof }, + { ehdr_64L11_tom, ehdr_64L11_tof }, + { half_64L__tom, half_64L__tof }, + { off_64L__tom, off_64L__tof }, + { phdr_64L11_tom, phdr_64L11_tof }, + { rela_64L11_tom, rela_64L11_tof }, + { rel_64L11_tom, rel_64L11_tof }, + { shdr_64L11_tom, shdr_64L11_tof }, + { sword_64L__tom, sword_64L__tof }, + { sym_64L11_tom, sym_64L11_tof }, + { word_64L__tom, word_64L__tof }, + { sxword_64L__tom, sxword_64L__tof }, + { xword_64L__tom, xword_64L__tof }, +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_64L11_tom, _elf_verdef_64L11_tof }, + { _elf_verneed_64L11_tom, _elf_verneed_64L11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, + { + { byte_copy, byte_copy }, + { addr_64M__tom, addr_64M__tof }, + { dyn_64M11_tom, dyn_64M11_tof }, + { ehdr_64M11_tom, ehdr_64M11_tof }, + { half_64M__tom, half_64M__tof }, + { off_64M__tom, off_64M__tof }, + { phdr_64M11_tom, phdr_64M11_tof }, + { rela_64M11_tom, rela_64M11_tof }, + { rel_64M11_tom, rel_64M11_tof }, + { shdr_64M11_tom, shdr_64M11_tof }, + { sword_64M__tom, sword_64M__tof }, + { sym_64M11_tom, sym_64M11_tof }, + { word_64M__tom, word_64M__tof }, + { sxword_64M__tom, sxword_64M__tof }, + { xword_64M__tom, xword_64M__tof }, +#if __LIBELF_SYMBOL_VERSIONS + { _elf_verdef_64M11_tom, _elf_verdef_64M11_tof }, + { _elf_verneed_64M11_tom, _elf_verneed_64M11_tof }, +#else /* __LIBELF_SYMBOL_VERSIONS */ + { 0, 0 }, + { 0, 0 }, +#endif /* __LIBELF_SYMBOL_VERSIONS */ + }, +}; + +/* + * main translation table (64-bit) + */ +#if PIC +static xltab* +#else /* PIC */ +static const xltab *const +#endif /* PIC */ +xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = { + { xlate64_11, }, +}; + +#define translator(sv,dv,enc,type,d) \ + (xlate64[(sv) - EV_NONE - 1] \ + [(dv) - EV_NONE - 1] \ + [(enc) - ELFDATA2LSB] \ + [(type) - ELF_T_BYTE] \ + [d]) + +/* + * destination buffer size + */ +size_t +_elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) { + Elf_Type type = src->d_type; + unsigned sv = src->d_version; + xlator op; + + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return (size_t)-1; + } + if (tof) { + /* + * Encoding doesn't really matter (the translator only looks at + * the source, which resides in memory), but we need a proper + * encoding to select a translator... + */ + encode = ELFDATA2LSB; + } + else if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return (size_t)-1; + } + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + if (!(op = translator(sv, dv, encode, type, tof))) { + seterr(ERROR_UNKNOWN_TYPE); + return (size_t)-1; + } + return (*op)(NULL, src->d_buf, src->d_size); +} + +/* + * direction-independent translation + */ +static Elf_Data* +elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) { + Elf_Type type; + int dv; + int sv; + size_t dsize; + size_t tmp; + xlator op; + + if (!src || !dst) { + return NULL; + } + if (!src->d_buf || !dst->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (!valid_encoding(encode)) { + seterr(ERROR_UNKNOWN_ENCODING); + return NULL; + } + sv = src->d_version; + dv = dst->d_version; + if (!valid_version(sv) || !valid_version(dv)) { + seterr(ERROR_UNKNOWN_VERSION); + return NULL; + } + type = src->d_type; + if (!valid_type(type)) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + op = translator(sv, dv, encode, type, tof); + if (!op) { + seterr(ERROR_UNKNOWN_TYPE); + return NULL; + } + dsize = (*op)(NULL, src->d_buf, src->d_size); + if (dsize == (size_t)-1) { + return NULL; + } + if (dst->d_size < dsize) { + seterr(ERROR_DST2SMALL); + return NULL; + } + if (dsize) { + tmp = (*op)(dst->d_buf, src->d_buf, src->d_size); + if (tmp == (size_t)-1) { + return NULL; + } + elf_assert(tmp == dsize); + } + dst->d_size = dsize; + dst->d_type = type; + return dst; +} + +/* + * finally, the "official" translation functions + */ +Elf_Data* +elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf64_xlate(dst, src, encode, 0); +} + +Elf_Data* +elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) { + return elf64_xlate(dst, src, encode, 1); +} + +Elf_Data* +gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + return elf32_xlatetom(dst, src, encode); + } + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetom(dst, src, encode); + } + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} + +Elf_Data* +gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + return elf32_xlatetof(dst, src, encode); + } + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetof(dst, src, encode); + } + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} + +#endif /* __LIBELF64__ */ diff --git a/external/libelf/src/assert.c b/external/libelf/src/assert.c new file mode 100644 index 00000000..18bd0416 --- /dev/null +++ b/external/libelf/src/assert.c @@ -0,0 +1,33 @@ +/* +assert.c - assert function for libelf. +Copyright (C) 1999 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: assert.c,v 1.5 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#include + +void +__elf_assert(const char *file, unsigned line, const char *cond) { + fprintf(stderr, "%s:%u: libelf assertion failure: %s\n", + file, line, cond); + abort(); +} diff --git a/external/libelf/src/begin.c b/external/libelf/src/begin.c new file mode 100644 index 00000000..1a7a2290 --- /dev/null +++ b/external/libelf/src/begin.c @@ -0,0 +1,429 @@ +/* + * begin.c - implementation of the elf_begin(3) and elf_memory(3) functions. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: begin.c,v 1.22 2009/11/01 13:04:19 michael Exp $"; +#endif /* lint */ + +static const Elf _elf_init = INIT_ELF; +static const char fmag[] = ARFMAG; + +static unsigned long +getnum(const char *str, size_t len, int base, size_t *err) { + unsigned long result = 0; + + while (len && *str == ' ') { + str++; len--; + } + while (len && *str >= '0' && (*str - '0') < base) { + result = base * result + *str++ - '0'; len--; + } + while (len && *str == ' ') { + str++; len--; + } + if (len) { + *err = len; + } + return result; +} + +static void +_elf_init_ar(Elf *elf) { + struct ar_hdr *hdr; + size_t offset; + size_t size; + size_t err = 0; + + elf->e_kind = ELF_K_AR; + elf->e_idlen = SARMAG; + elf->e_off = SARMAG; + + /* process special members */ + offset = SARMAG; + while (!elf->e_strtab && offset + sizeof(*hdr) <= elf->e_size) { + hdr = (struct ar_hdr*)(elf->e_data + offset); + if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) { + break; + } + if (hdr->ar_name[0] != '/') { + break; + } + size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err); + if (err || !size) { + break; + } + offset += sizeof(*hdr); + if (offset + size > elf->e_size) { + break; + } + if (hdr->ar_name[1] == '/' && hdr->ar_name[2] == ' ') { + elf->e_strtab = elf->e_data + offset; + elf->e_strlen = size; + break; + } + if (hdr->ar_name[1] != ' ') { + break; + } + /* + * Windows (.lib) archives provide two symbol tables + * The first one is the one we want. + */ + if (!elf->e_symtab) { + elf->e_symtab = elf->e_data + offset; + elf->e_symlen = size; + } + offset += size + (size & 1); + } +} + +static Elf_Arhdr* +_elf_arhdr(Elf *arf) { + struct ar_hdr *hdr; + Elf_Arhdr *arhdr; + size_t namelen; + size_t tmp; + char *name; + size_t err = 0; + + if (arf->e_off == arf->e_size) { + /* no error! */ + return NULL; + } + if (arf->e_off < 0 || arf->e_off > arf->e_size) { + seterr(ERROR_OUTSIDE); + return NULL; + } + if (arf->e_off + sizeof(*hdr) > arf->e_size) { + seterr(ERROR_TRUNC_ARHDR); + return NULL; + } + elf_assert(arf->e_data != NULL); + hdr = (struct ar_hdr*)(arf->e_data + arf->e_off); + if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) { + seterr(ERROR_ARFMAG); + return NULL; + } + + name = hdr->ar_name; + for (namelen = sizeof(hdr->ar_name); namelen > 0; namelen--) { + if (name[namelen - 1] != ' ') { + break; + } + } + if (name[0] == '/') { + if (name[1] >= '0' && name[1] <= '9') { + if (!arf->e_strtab) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + tmp = getnum(&name[1], namelen - 1, 10, &err); + if (err) { + seterr(ERROR_ARSPECIAL); + return NULL; + } + if (tmp < 0 || tmp >= arf->e_strlen) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + for (namelen = tmp; namelen < arf->e_strlen; namelen++) { + if (arf->e_strtab[namelen] == '/') { + break; + } + } + if (namelen == arf->e_strlen) { + seterr(ERROR_ARSTRTAB); + return NULL; + } + name = arf->e_strtab + tmp; + namelen -= tmp; + } + else if (namelen != 1 && !(namelen == 2 && name[1] == '/')) { + seterr(ERROR_ARSPECIAL); + return NULL; + } + } + else if (namelen > 0 && name[namelen - 1] == '/') { + namelen--; + } + /* XXX some broken software omits the trailing slash + else { + namelen = 0; + } + */ + + if (!(arhdr = (Elf_Arhdr*)malloc(sizeof(*arhdr) + + sizeof(hdr->ar_name) + namelen + 2))) { + seterr(ERROR_MEM_ARHDR); + return NULL; + } + + arhdr->ar_name = NULL; + arhdr->ar_rawname = (char*)(arhdr + 1); + arhdr->ar_date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10, &err); + arhdr->ar_uid = getnum(hdr->ar_uid, sizeof(hdr->ar_uid), 10, &err); + arhdr->ar_gid = getnum(hdr->ar_gid, sizeof(hdr->ar_gid), 10, &err); + arhdr->ar_mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8, &err); + arhdr->ar_size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err); + if (err) { + free(arhdr); + seterr(ERROR_ARHDR); + return NULL; + } + if (arf->e_off + sizeof(struct ar_hdr) + arhdr->ar_size > arf->e_size) { + free(arhdr); + seterr(ERROR_TRUNC_MEMBER); + return NULL; + } + + memcpy(arhdr->ar_rawname, hdr->ar_name, sizeof(hdr->ar_name)); + arhdr->ar_rawname[sizeof(hdr->ar_name)] = '\0'; + + if (namelen) { + arhdr->ar_name = arhdr->ar_rawname + sizeof(hdr->ar_name) + 1; + memcpy(arhdr->ar_name, name, namelen); + arhdr->ar_name[namelen] = '\0'; + } + + return arhdr; +} + +static void +_elf_check_type(Elf *elf, size_t size) { + elf->e_idlen = size; + if (size >= EI_NIDENT && !memcmp(elf->e_data, ELFMAG, SELFMAG)) { + elf->e_kind = ELF_K_ELF; + elf->e_idlen = EI_NIDENT; + elf->e_class = elf->e_data[EI_CLASS]; + elf->e_encoding = elf->e_data[EI_DATA]; + elf->e_version = elf->e_data[EI_VERSION]; + } + else if (size >= SARMAG && !memcmp(elf->e_data, ARMAG, SARMAG)) { + _elf_init_ar(elf); + } +} + +Elf* +elf_begin(int fd, Elf_Cmd cmd, Elf *ref) { + Elf_Arhdr *arhdr = NULL; + size_t size = 0; + off_t off; + Elf *elf; + + elf_assert(_elf_init.e_magic == ELF_MAGIC); + if (_elf_version == EV_NONE) { + seterr(ERROR_VERSION_UNSET); + return NULL; + } + else if (cmd == ELF_C_NULL) { + return NULL; + } + else if (cmd == ELF_C_WRITE) { + ref = NULL; + } + else if (cmd != ELF_C_READ && cmd != ELF_C_RDWR) { + seterr(ERROR_INVALID_CMD); + return NULL; + } + else if (ref) { + elf_assert(ref->e_magic == ELF_MAGIC); + if (!ref->e_readable || (cmd == ELF_C_RDWR && !ref->e_writable)) { + seterr(ERROR_CMDMISMATCH); + return NULL; + } + if (ref->e_kind != ELF_K_AR) { + ref->e_count++; + return ref; + } + if (cmd == ELF_C_RDWR) { + seterr(ERROR_MEMBERWRITE); + return NULL; + } + if (ref->e_memory) { + fd = ref->e_fd; + } + else if (fd != ref->e_fd) { + seterr(ERROR_FDMISMATCH); + return NULL; + } + if (!(arhdr = _elf_arhdr(ref))) { + return NULL; + } + size = arhdr->ar_size; + } + else if ((off = lseek(fd, (off_t)0, SEEK_END)) == (off_t)-1 + || (off_t)(size = off) != off) { + seterr(ERROR_IO_GETSIZE); + return NULL; + } + + if (!(elf = (Elf*)malloc(sizeof(Elf)))) { + seterr(ERROR_MEM_ELF); + return NULL; + } + *elf = _elf_init; + elf->e_fd = fd; + elf->e_parent = ref; + elf->e_size = elf->e_dsize = size; + + if (cmd != ELF_C_READ) { + elf->e_writable = 1; + } + if (cmd != ELF_C_WRITE) { + elf->e_readable = 1; + } + else { + return elf; + } + + if (ref) { + size_t offset = ref->e_off + sizeof(struct ar_hdr); + Elf *xelf; + + elf_assert(arhdr); + elf->e_arhdr = arhdr; + elf->e_base = ref->e_base + offset; + /* + * Share the archive's memory image. To avoid + * multiple independent elf descriptors if the + * same member is requested twice, scan the list + * of open members for duplicates. + * + * I don't know how SVR4 handles this case. Don't rely on it. + */ + for (xelf = ref->e_members; xelf; xelf = xelf->e_link) { + elf_assert(xelf->e_parent == ref); + if (xelf->e_base == elf->e_base) { + free(arhdr); + free(elf); + xelf->e_count++; + return xelf; + } + } + if (size == 0) { + elf->e_data = NULL; + } +#if 1 + else { + /* + * Archive members may be misaligned. Freezing them will + * cause libelf to allocate buffers for translated data, + * which should be properly aligned in all cases. + */ + elf_assert(!ref->e_cooked); + elf->e_data = elf->e_rawdata = ref->e_data + offset; + } +#else + else if (ref->e_data == ref->e_rawdata) { + elf_assert(!ref->e_cooked); + /* + * archive is frozen - freeze member, too + */ + elf->e_data = elf->e_rawdata = ref->e_data + offset; + } + else { + elf_assert(!ref->e_memory); + elf->e_data = ref->e_data + offset; + /* + * The member's memory image may have been modified if + * the member has been processed before. Since we need the + * original image, we have to re-read the archive file. + * Will fail if the archive's file descriptor is disabled. + */ + if (!ref->e_cooked) { + ref->e_cooked = 1; + } + else if (!_elf_read(ref, elf->e_data, offset, size)) { + free(arhdr); + free(elf); + return NULL; + } + } +#endif + elf->e_next = offset + size + (size & 1); + elf->e_disabled = ref->e_disabled; + elf->e_memory = ref->e_memory; + /* parent/child linking */ + elf->e_link = ref->e_members; + ref->e_members = elf; + ref->e_count++; + /* Slowaris compatibility - do not rely on this! */ + ref->e_off = elf->e_next; + } + else if (size) { +#if HAVE_MMAP + /* + * Using mmap on writable files will interfere with elf_update + */ + if (!elf->e_writable && (elf->e_data = _elf_mmap(elf))) { + elf->e_unmap_data = 1; + } + else +#endif /* HAVE_MMAP */ + if (!(elf->e_data = _elf_read(elf, NULL, 0, size))) { + free(elf); + return NULL; + } + } + + _elf_check_type(elf, size); + return elf; +} + +Elf* +elf_memory(char *image, size_t size) { + Elf *elf; + + elf_assert(_elf_init.e_magic == ELF_MAGIC); + if (_elf_version == EV_NONE) { + seterr(ERROR_VERSION_UNSET); + return NULL; + } + else if (size == 0 || image == NULL) { + /* TODO: set error code? */ + return NULL; + } + + if (!(elf = (Elf*)malloc(sizeof(Elf)))) { + seterr(ERROR_MEM_ELF); + return NULL; + } + *elf = _elf_init; + elf->e_size = elf->e_dsize = size; + elf->e_data = elf->e_rawdata = image; + elf->e_readable = 1; + elf->e_disabled = 1; + elf->e_memory = 1; + + _elf_check_type(elf, size); + return elf; +} + +#if __LIBELF64 + +int +gelf_getclass(Elf *elf) { + if (elf && elf->e_kind == ELF_K_ELF && valid_class(elf->e_class)) { + return elf->e_class; + } + return ELFCLASSNONE; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/byteswap.h b/external/libelf/src/byteswap.h new file mode 100644 index 00000000..7526d123 --- /dev/null +++ b/external/libelf/src/byteswap.h @@ -0,0 +1,95 @@ +/* +byteswap.h - functions and macros for byte swapping. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +/* @(#) $Id: byteswap.h,v 1.7 2008/05/23 08:15:34 michael Exp $ */ + +#ifndef _BYTESWAP_H +#define _BYTESWAP_H + +#define lu(from,i,s) (((__libelf_u32_t)((unsigned char*)(from))[i])<<(s)) +#define li(from,i,s) (((__libelf_i32_t)(( signed char*)(from))[i])<<(s)) + +#define __load_u16L(from) ((__libelf_u32_t) \ + (lu(from,1,8) | lu(from,0,0))) +#define __load_u16M(from) ((__libelf_u32_t) \ + (lu(from,0,8) | lu(from,1,0))) +#define __load_i16L(from) ((__libelf_i32_t) \ + (li(from,1,8) | lu(from,0,0))) +#define __load_i16M(from) ((__libelf_i32_t) \ + (li(from,0,8) | lu(from,1,0))) + +#define __load_u32L(from) ((__libelf_u32_t) \ + (lu(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0))) +#define __load_u32M(from) ((__libelf_u32_t) \ + (lu(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0))) +#define __load_i32L(from) ((__libelf_i32_t) \ + (li(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0))) +#define __load_i32M(from) ((__libelf_i32_t) \ + (li(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0))) + +#define su(to,i,v,s) (((char*)(to))[i]=((__libelf_u32_t)(v)>>(s))) +#define si(to,i,v,s) (((char*)(to))[i]=((__libelf_i32_t)(v)>>(s))) + +#define __store_u16L(to,v) \ + (su(to,1,v,8), su(to,0,v,0)) +#define __store_u16M(to,v) \ + (su(to,0,v,8), su(to,1,v,0)) +#define __store_i16L(to,v) \ + (si(to,1,v,8), si(to,0,v,0)) +#define __store_i16M(to,v) \ + (si(to,0,v,8), si(to,1,v,0)) + +#define __store_u32L(to,v) \ + (su(to,3,v,24), su(to,2,v,16), su(to,1,v,8), su(to,0,v,0)) +#define __store_u32M(to,v) \ + (su(to,0,v,24), su(to,1,v,16), su(to,2,v,8), su(to,3,v,0)) +#define __store_i32L(to,v) \ + (si(to,3,v,24), si(to,2,v,16), si(to,1,v,8), si(to,0,v,0)) +#define __store_i32M(to,v) \ + (si(to,0,v,24), si(to,1,v,16), si(to,2,v,8), si(to,3,v,0)) + +#if __LIBELF64 + +/* + * conversion functions from swap64.c + */ +extern __libelf_u64_t _elf_load_u64L(const unsigned char *from); +extern __libelf_u64_t _elf_load_u64M(const unsigned char *from); +extern __libelf_i64_t _elf_load_i64L(const unsigned char *from); +extern __libelf_i64_t _elf_load_i64M(const unsigned char *from); +extern void _elf_store_u64L(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_u64M(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_i64L(unsigned char *to, __libelf_u64_t v); +extern void _elf_store_i64M(unsigned char *to, __libelf_u64_t v); + +/* + * aliases for existing conversion code + */ +#define __load_u64L _elf_load_u64L +#define __load_u64M _elf_load_u64M +#define __load_i64L _elf_load_i64L +#define __load_i64M _elf_load_i64M +#define __store_u64L _elf_store_u64L +#define __store_u64M _elf_store_u64M +#define __store_i64L _elf_store_i64L +#define __store_i64M _elf_store_i64M + +#endif /* __LIBELF64 */ + +#endif /* _BYTESWAP_H */ diff --git a/external/libelf/src/checksum.c b/external/libelf/src/checksum.c new file mode 100644 index 00000000..f9e964bc --- /dev/null +++ b/external/libelf/src/checksum.c @@ -0,0 +1,178 @@ +/* +checksum.c - implementation of the elf{32,64}_checksum(3) functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: checksum.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +/* + * Compatibility note: + * + * The algorithm used in {elf32,elf64,gelf}_checksum() does not seem to + * be documented. I hope I got it right. My implementation does the + * following: + * + * - skip sections that do not have the SHF_ALLOC flag set + * - skip sections of type SHT_NULL, SHT_NOBITS, SHT_DYNSYM and + * SHT_DYNAMIC + * - add all data bytes from the remaining sections, modulo 2**32 + * - add upper and lower half of the result + * - subtract 0xffff if the result is > 0xffff + * - if any error occurs, return 0L + */ + +static int +skip_section(Elf_Scn *scn, unsigned cls) { + if (cls == ELFCLASS32) { + Elf32_Shdr *shdr = &scn->s_shdr32; + + if (!(shdr->sh_flags & SHF_ALLOC)) { + return 1; + } + switch (shdr->sh_type) { + case SHT_NULL: + case SHT_NOBITS: + /* Solaris seems to ignore these, too */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + return 1; + } + } +#if __LIBELF64 + else if (cls == ELFCLASS64) { + Elf64_Shdr *shdr = &scn->s_shdr64; + + if (!(shdr->sh_flags & SHF_ALLOC)) { + return 1; + } + switch (shdr->sh_type) { + case SHT_NULL: + case SHT_NOBITS: + /* Solaris seems to ignore these, too */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + return 1; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + } + return 0; +} + +static long +add_bytes(unsigned char *ptr, size_t len) { + long csum = 0; + + while (len--) { + csum += *ptr++; + } + return csum; +} + +static long +_elf_csum(Elf *elf) { + long csum = 0; + Elf_Data *data; + Elf_Scn *scn; + + if (!elf->e_ehdr && !_elf_cook(elf)) { + /* propagate errors from _elf_cook */ + return 0L; + } + seterr(0); + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + if (scn->s_index == SHN_UNDEF || skip_section(scn, elf->e_class)) { + continue; + } + data = NULL; + while ((data = elf_getdata(scn, data))) { + if (data->d_size) { + if (data->d_buf == NULL) { + seterr(ERROR_NULLBUF); + return 0L; + } + csum += add_bytes(data->d_buf, data->d_size); + } + } + } + if (_elf_errno) { + return 0L; + } + csum = (csum & 0xffff) + ((csum >> 16) & 0xffff); + if (csum > 0xffff) { + csum -= 0xffff; + } + return csum; +} + +long +elf32_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != ELFCLASS32) { + seterr(ERROR_CLASSMISMATCH); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +#if __LIBELF64 + +long +elf64_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class != ELFCLASS64) { + seterr(ERROR_CLASSMISMATCH); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +long +gelf_checksum(Elf *elf) { + if (elf) { + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + } + else { + return _elf_csum(elf); + } + } + return 0L; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/cntl.c b/external/libelf/src/cntl.c new file mode 100644 index 00000000..3f7c5d47 --- /dev/null +++ b/external/libelf/src/cntl.c @@ -0,0 +1,71 @@ +/* +cntl.c - implementation of the elf_cntl(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: cntl.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +int +elf_cntl(Elf *elf, Elf_Cmd cmd) { + Elf_Scn *scn; + Elf *child; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (cmd == ELF_C_FDREAD) { + if (!elf->e_readable) { + seterr(ERROR_WRONLY); + return -1; + } + } + else if (cmd != ELF_C_FDDONE) { + seterr(ERROR_INVALID_CMD); + return -1; + } + if (elf->e_disabled) { + return 0; + } + if (elf->e_kind == ELF_K_AR) { + for (child = elf->e_members; child; child = child->e_link) { + elf_assert(elf == child->e_parent); + if (elf_cntl(child, cmd)) { + return -1; + } + } + } + else if (elf->e_kind == ELF_K_ELF && cmd == ELF_C_FDREAD) { + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) { + continue; + } + else if (!elf_getdata(scn, NULL)) { + return -1; + } + } + } + elf->e_disabled = 1; + return 0; +} diff --git a/external/libelf/src/config.h b/external/libelf/src/config.h new file mode 100644 index 00000000..d3729618 --- /dev/null +++ b/external/libelf/src/config.h @@ -0,0 +1,164 @@ +/* + * lib/config.h.w32 - configuration file for W32 port + * Copyright (C) 2004 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @(#) $Id: config.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $ + */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you want to include extra debugging code */ +#define ENABLE_DEBUG 1 + +/* Define if memmove() does not copy overlapping arrays correctly */ +#undef HAVE_BROKEN_MEMMOVE + +/* Define if you have the catgets function. */ +#undef HAVE_CATGETS + +/* Define if you have the dgettext function. */ +#undef HAVE_DGETTEXT + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if struct nlist is declared in or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if you want 64-bit support (and your system supports it) */ +#define __LIBELF64 1 + +/* Define if you want 64-bit support, and are running IRIX */ +#undef __LIBELF64_IRIX + +/* Define if you want 64-bit support, and are running Linux */ +#undef __LIBELF64_LINUX + +/* Define if you want symbol versioning (and your system supports it) */ +#define __LIBELF_SYMBOL_VERSIONS 1 + +/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */ +#define __LIBELF_SUN_SYMBOL_VERSIONS 1 + +/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */ +#undef __LIBELF_GNU_SYMBOL_VERSIONS + +/* Define to a 64-bit signed integer type if one exists */ +#define __libelf_i64_t __int64 + +/* Define to a 64-bit unsigned integer type if one exists */ +#define __libelf_u64_t unsigned __int64 + +/* Define to a 32-bit signed integer type if one exists */ +#define __libelf_i32_t int + +/* Define to a 32-bit unsigned integer type if one exists */ +#define __libelf_u32_t unsigned int + +/* Define to a 16-bit signed integer type if one exists */ +#define __libelf_i16_t short int + +/* Define to a 16-bit unsigned integer type if one exists */ +#define __libelf_u16_t unsigned short int + +/* The number of bytes in a __int64. */ +#define SIZEOF___INT64 8 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* The number of bytes in a long long. */ +#define SIZEOF_LONG_LONG 0 + +/* The number of bytes in a short. */ +#define SIZEOF_SHORT 2 + +/* Define if you have the ftruncate function. */ +#undef HAVE_FTRUNCATE + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcmp function. */ +#define HAVE_MEMCMP 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the header file. */ +#undef HAVE_AR_H + +/* Define if you have the header file. */ +#undef HAVE_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GELF_H + +/* Define if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define if you have the header file. */ +#undef HAVE_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 diff --git a/external/libelf/src/cook.c b/external/libelf/src/cook.c new file mode 100644 index 00000000..066b6f2e --- /dev/null +++ b/external/libelf/src/cook.c @@ -0,0 +1,501 @@ +/* + * cook.c - read and translate ELF files. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: cook.c,v 1.29 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +const Elf_Scn _elf_scn_init = INIT_SCN; +const Scn_Data _elf_data_init = INIT_DATA; + +Elf_Type +_elf_scn_type(unsigned t) { + switch (t) { + case SHT_DYNAMIC: return ELF_T_DYN; + case SHT_DYNSYM: return ELF_T_SYM; + case SHT_HASH: return ELF_T_WORD; + case SHT_REL: return ELF_T_REL; + case SHT_RELA: return ELF_T_RELA; + case SHT_SYMTAB: return ELF_T_SYM; + case SHT_SYMTAB_SHNDX: return ELF_T_WORD; /* XXX: really? */ +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: return ELF_T_VDEF; + case SHT_SUNW_verneed: return ELF_T_VNEED; + case SHT_SUNW_versym: return ELF_T_HALF; +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: return ELF_T_VDEF; + case SHT_GNU_verneed: return ELF_T_VNEED; + case SHT_GNU_versym: return ELF_T_HALF; +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + } + return ELF_T_BYTE; +} + +/* + * Check for overflow on 32-bit systems + */ +#define overflow(a,b,t) (sizeof(a) < sizeof(t) && (t)(a) != (b)) + +#define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR: \ + ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR: \ + ERROR_INTERNAL)) +#define memerr(t) ((t)==ELF_T_EHDR?ERROR_MEM_EHDR: \ + ((t)==ELF_T_PHDR?ERROR_MEM_PHDR: \ + ERROR_INTERNAL)) + +Elf_Data* +_elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) { + if (elf->e_class == ELFCLASS32) { + return elf32_xlatetom(dst, src, elf->e_encoding); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + return elf64_xlatetom(dst, src, elf->e_encoding); + } +#endif /* __LIBELF64 */ + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +static char* +_elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) { + Elf_Data src, dst; + + elf_assert(valid_type(type)); + if (off < 0 || off > elf->e_size) { + seterr(ERROR_OUTSIDE); + return NULL; + } + + src.d_type = type; + src.d_version = elf->e_version; + src.d_size = _fsize(elf->e_class, src.d_version, type); + elf_assert(src.d_size); + if ((elf->e_size - off) < src.d_size) { + seterr(truncerr(type)); + return NULL; + } + + dst.d_version = _elf_version; + dst.d_size = _msize(elf->e_class, dst.d_version, type); + elf_assert(dst.d_size); + + if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) { + seterr(memerr(type)); + return NULL; + } + + elf_assert(elf->e_data); + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off; + } + else { + src.d_buf = elf->e_data + off; + } + + if (_elf_xlatetom(elf, &dst, &src)) { + return (char*)dst.d_buf; + } + if (dst.d_buf != buf) { + free(dst.d_buf); + } + return NULL; +} + +static int +_elf_cook_phdr(Elf *elf) { + size_t num, off, entsz; + + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum; + off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff; + entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum; + off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff; + entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (off) { + Elf_Scn *scn; + size_t size; + unsigned i; + char *p; + + if (num == PN_XNUM) { + /* + * Overflow in ehdr->e_phnum. + * Get real value from first SHDR. + */ + if (!(scn = elf->e_scn_1)) { + seterr(ERROR_NOSUCHSCN); + return 0; + } + if (elf->e_class == ELFCLASS32) { + num = scn->s_shdr32.sh_info; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = scn->s_shdr64.sh_info; + } +#endif /* __LIBELF64 */ + /* we already had this + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + */ + } + + size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR); + elf_assert(size); +#if ENABLE_EXTENDED_FORMAT + if (entsz < size) { +#else /* ENABLE_EXTENDED_FORMAT */ + if (entsz != size) { +#endif /* ENABLE_EXTENDED_FORMAT */ + seterr(ERROR_EHDR_PHENTSIZE); + return 0; + } + size = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + elf_assert(size); + if (!(p = malloc(num * size))) { + seterr(memerr(ELF_T_PHDR)); + return 0; + } + for (i = 0; i < num; i++) { + if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) { + free(p); + return 0; + } + } + elf->e_phdr = p; + elf->e_phnum = num; + } + return 1; +} + +static int +_elf_cook_shdr(Elf *elf) { + size_t num, off, entsz; + + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum; + off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff; + entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum; + off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff; + entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (off) { + struct tmp { + Elf_Scn scn; + Scn_Data data; + } *head; + Elf_Data src, dst; + Elf_Scn *scn; + Scn_Data *sd; + unsigned i; + + if (off < 0 || off > elf->e_size) { + seterr(ERROR_OUTSIDE); + return 0; + } + + src.d_type = ELF_T_SHDR; + src.d_version = elf->e_version; + src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR); + elf_assert(src.d_size); +#if ENABLE_EXTENDED_FORMAT + if (entsz < src.d_size) { +#else /* ENABLE_EXTENDED_FORMAT */ + if (entsz != src.d_size) { +#endif /* ENABLE_EXTENDED_FORMAT */ + seterr(ERROR_EHDR_SHENTSIZE); + return 0; + } + dst.d_version = EV_CURRENT; + + if (num == 0) { + union { + Elf32_Shdr sh32; +#if __LIBELF64 + Elf64_Shdr sh64; +#endif /* __LIBELF64 */ + } u; + + /* + * Overflow in ehdr->e_shnum. + * Get real value from first SHDR. + */ + if (elf->e_size - off < entsz) { + seterr(ERROR_TRUNC_SHDR); + return 0; + } + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off; + } + else { + src.d_buf = elf->e_data + off; + } + dst.d_buf = &u; + dst.d_size = sizeof(u); + if (!_elf_xlatetom(elf, &dst, &src)) { + return 0; + } + elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR)); + elf_assert(dst.d_type == ELF_T_SHDR); + if (elf->e_class == ELFCLASS32) { + num = u.sh32.sh_size; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = u.sh64.sh_size; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(num, u.sh64.sh_size, Elf64_Xword)) { + seterr(ERROR_OUTSIDE); + return 0; + } + } +#endif /* __LIBELF64 */ + } + + if ((elf->e_size - off) / entsz < num) { + seterr(ERROR_TRUNC_SHDR); + return 0; + } + + if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) { + seterr(ERROR_MEM_SCN); + return 0; + } + for (scn = NULL, i = num; i-- > 0; ) { + head[i].scn = _elf_scn_init; + head[i].data = _elf_data_init; + head[i].scn.s_link = scn; + if (!scn) { + elf->e_scn_n = &head[i].scn; + } + scn = &head[i].scn; + sd = &head[i].data; + + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + off + i * entsz; + } + else { + src.d_buf = elf->e_data + off + i * entsz; + } + dst.d_buf = &scn->s_uhdr; + dst.d_size = sizeof(scn->s_uhdr); + if (!_elf_xlatetom(elf, &dst, &src)) { + elf->e_scn_n = NULL; + free(head); + return 0; + } + elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR)); + elf_assert(dst.d_type == ELF_T_SHDR); + + scn->s_elf = elf; + scn->s_index = i; + scn->s_data_1 = sd; + scn->s_data_n = sd; + + sd->sd_scn = scn; + + if (elf->e_class == ELFCLASS32) { + Elf32_Shdr *shdr = &scn->s_shdr32; + + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + sd->sd_data.d_align = shdr->sh_addralign; + sd->sd_data.d_type = _elf_scn_type(scn->s_type); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + Elf64_Shdr *shdr = &scn->s_shdr64; + + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + sd->sd_data.d_align = shdr->sh_addralign; + /* + * Check for overflow on 32-bit systems + */ + if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword) + || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off) + || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) { + seterr(ERROR_OUTSIDE); + return 0; + } + sd->sd_data.d_type = _elf_scn_type(scn->s_type); + /* + * QUIRKS MODE: + * + * Some 64-bit architectures use 64-bit entries in the + * .hash section. This violates the ELF standard, and + * should be fixed. It's mostly harmless as long as the + * binary and the machine running your program have the + * same byte order, but you're in trouble if they don't, + * and if the entry size is wrong. + * + * As a workaround, I let libelf guess the right size + * for the binary. This relies pretty much on the fact + * that the binary provides correct data in the section + * headers. If it doesn't, it's probably broken anyway. + * Therefore, libelf uses a standard conforming value + * when it's not absolutely sure. + */ + if (scn->s_type == SHT_HASH) { + int override = 0; + + /* + * sh_entsize must reflect the entry size + */ + if (shdr->sh_entsize == ELF64_FSZ_ADDR) { + override++; + } + /* + * sh_size must be a multiple of sh_entsize + */ + if (shdr->sh_size % ELF64_FSZ_ADDR == 0) { + override++; + } + /* + * There must be room for at least 2 entries + */ + if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) { + override++; + } + /* + * sh_addralign must be correctly set + */ + if (shdr->sh_addralign == ELF64_FSZ_ADDR) { + override++; + } + /* + * The section must be properly aligned + */ + if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) { + override++; + } + /* XXX: also look at the data? */ + /* + * Make a conservative decision... + */ + if (override >= 5) { + sd->sd_data.d_type = ELF_T_ADDR; + } + } + /* + * END QUIRKS MODE. + */ + } +#endif /* __LIBELF64 */ + /* we already had this + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + */ + + sd->sd_data.d_size = scn->s_size; + sd->sd_data.d_version = _elf_version; + } + elf_assert(scn == &head[0].scn); + elf->e_scn_1 = &head[0].scn; + head[0].scn.s_freeme = 1; + } + return 1; +} + +static int +_elf_cook_file(Elf *elf) { + elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0); + if (!elf->e_ehdr) { + return 0; + } + /* + * Note: _elf_cook_phdr may require the first section header! + */ + if (!_elf_cook_shdr(elf)) { + return 0; + } + if (!_elf_cook_phdr(elf)) { + return 0; + } + return 1; +} + +int +_elf_cook(Elf *elf) { + elf_assert(_elf_scn_init.s_magic == SCN_MAGIC); + elf_assert(_elf_data_init.sd_magic == DATA_MAGIC); + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_kind == ELF_K_ELF); + elf_assert(!elf->e_ehdr); + if (!valid_version(elf->e_version)) { + seterr(ERROR_UNKNOWN_VERSION); + } + else if (!valid_encoding(elf->e_encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + } + else if (valid_class(elf->e_class)) { + return _elf_cook_file(elf); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; +} diff --git a/external/libelf/src/data.c b/external/libelf/src/data.c new file mode 100644 index 00000000..53d78c32 --- /dev/null +++ b/external/libelf/src/data.c @@ -0,0 +1,36 @@ +/* + * data.c - libelf internal variables. + * Copyright (C) 1995 - 1998, 2007 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: data.c,v 1.8 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +unsigned _elf_version = EV_NONE; +int _elf_errno = 0; +int _elf_fill = 0; + +#if ENABLE_SANITY_CHECKS +#define SANITY_CHECKS -1 +#else +#define SANITY_CHECKS 0 +#endif + +int _elf_sanity_checks = SANITY_CHECKS; diff --git a/external/libelf/src/end.c b/external/libelf/src/end.c new file mode 100644 index 00000000..c6042399 --- /dev/null +++ b/external/libelf/src/end.c @@ -0,0 +1,118 @@ +/* + * end.c - implementation of the elf_end(3) function. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: end.c,v 1.12 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static void +_elf_free(void *ptr) { + if (ptr) { + free(ptr); + } +} + +static void +_elf_free_scns(Elf *elf, Elf_Scn *scn) { + Scn_Data *sd, *tmp; + Elf_Scn *freescn; + + for (freescn = NULL; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data) { + _elf_free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data) { + _elf_free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + _elf_free(freescn); + freescn = scn; + } + } + _elf_free(freescn); +} + +int +elf_end(Elf *elf) { + Elf **siblings; + + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (--elf->e_count) { + return elf->e_count; + } + if (elf->e_parent) { + elf_assert(elf->e_parent->e_magic == ELF_MAGIC); + elf_assert(elf->e_parent->e_kind == ELF_K_AR); + siblings = &elf->e_parent->e_members; + while (*siblings) { + if (*siblings == elf) { + *siblings = elf->e_link; + break; + } + siblings = &(*siblings)->e_link; + } + elf_end(elf->e_parent); + _elf_free(elf->e_arhdr); + } +#if HAVE_MMAP + else if (elf->e_unmap_data) { + munmap(elf->e_data, elf->e_size); + } +#endif /* HAVE_MMAP */ + else if (!elf->e_memory) { + _elf_free(elf->e_data); + } + _elf_free_scns(elf, elf->e_scn_1); + if (elf->e_rawdata != elf->e_data) { + _elf_free(elf->e_rawdata); + } + if (elf->e_free_syms) { + _elf_free(elf->e_symtab); + } + _elf_free(elf->e_ehdr); + _elf_free(elf->e_phdr); + free(elf); + return 0; +} diff --git a/external/libelf/src/errmsg.c b/external/libelf/src/errmsg.c new file mode 100644 index 00000000..883243fb --- /dev/null +++ b/external/libelf/src/errmsg.c @@ -0,0 +1,77 @@ +/* + * errmsg.c - implementation of the elf_errmsg(3) function. + * Copyright (C) 1995 - 1999, 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: errmsg.c,v 1.11 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#if HAVE_DGETTEXT +# undef HAVE_CATGETS +# include +#else /* HAVE_DGETTEXT */ +# define dgettext(dom, str) str +#endif /* HAVE_DGETTEXT */ + +#if HAVE_CATGETS +# include +static nl_catd _libelf_cat = (nl_catd)0; +#endif /* HAVE_CATGETS */ + +#if HAVE_DGETTEXT || HAVE_CATGETS +static const char domain[] = "libelf"; +#endif /* HAVE_DGETTEXT || HAVE_CATGETS */ + +#if PIC +static const char *_messages[] = { +#else /* PIC */ +static const char *const _messages[] = { +#endif /* PIC */ +#define __err__(a,b) b, +#include /* include string tables from errors.h */ +#undef __err__ +}; + +const char* +elf_errmsg(int err) { + if (err == 0) { + err = _elf_errno; + if (err == 0) { + return NULL; + } + } + else if (err == -1) { + err = _elf_errno; + } + + if (err < 0 || err >= ERROR_NUM || _messages[err] == NULL) { + err = ERROR_UNKNOWN; + } + +#if HAVE_CATGETS + if (_libelf_cat == (nl_catd)0) { + _libelf_cat = catopen(domain, 0); + } + if (_libelf_cat != (nl_catd)-1) { + return catgets(_libelf_cat, 1, err + 1, _messages[err]); + } +#endif /* HAVE_CATGETS */ + return dgettext(domain, _messages[err]); +} diff --git a/external/libelf/src/errno.c b/external/libelf/src/errno.c new file mode 100644 index 00000000..19023229 --- /dev/null +++ b/external/libelf/src/errno.c @@ -0,0 +1,32 @@ +/* +errno.c - implementation of the elf_errno(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: errno.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +int +elf_errno(void) { + int tmp = _elf_errno; + + _elf_errno = 0; + return tmp; +} diff --git a/external/libelf/src/errors.h b/external/libelf/src/errors.h new file mode 100644 index 00000000..80ee70b9 --- /dev/null +++ b/external/libelf/src/errors.h @@ -0,0 +1,100 @@ +/* + * errors.h - exhaustive list of all error codes and messages for libelf. + * Copyright (C) 1995 - 2003, 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: errors.h,v 1.18 2008/05/23 08:15:34 michael Exp $ */ + +/* dummy for xgettext */ +#define _(str) str + +__err__(ERROR_OK, _("no error")) +__err__(ERROR_UNKNOWN, _("unknown error")) +__err__(ERROR_INTERNAL, _("Internal error: unknown reason")) +__err__(ERROR_UNIMPLEMENTED, _("Internal error: not implemented")) +__err__(ERROR_WRONLY, _("Request error: cntl(ELF_C_FDREAD) on write-only file")) +__err__(ERROR_INVALID_CMD, _("Request error: invalid ELF_C_* argument")) +__err__(ERROR_FDDISABLED, _("Request error: file descriptor disabled")) +__err__(ERROR_NOTARCHIVE, _("Request error: not an archive")) +__err__(ERROR_BADOFF, _("Request error: offset out of range")) +__err__(ERROR_UNKNOWN_VERSION, _("Request error: unknown ELF version")) +__err__(ERROR_CMDMISMATCH, _("Request error: ELF_C_* argument does not match")) +__err__(ERROR_MEMBERWRITE, _("Request error: archive member begin() for writing")) +__err__(ERROR_FDMISMATCH, _("Request error: archive/member file descriptor mismatch")) +__err__(ERROR_NOTELF, _("Request error: not an ELF file")) +__err__(ERROR_CLASSMISMATCH, _("Request error: class file/memory mismatch")) +__err__(ERROR_UNKNOWN_TYPE, _("Request error: invalid ELF_T_* argument")) +__err__(ERROR_UNKNOWN_ENCODING, _("Request error: unknown data encoding")) +__err__(ERROR_DST2SMALL, _("Request error: destination buffer too small")) +__err__(ERROR_NULLBUF, _("Request error: d_buf is NULL")) +__err__(ERROR_UNKNOWN_CLASS, _("Request error: unknown ELF class")) +__err__(ERROR_ELFSCNMISMATCH, _("Request error: section does not belong to file")) +__err__(ERROR_NOSUCHSCN, _("Request error: no section at index")) +__err__(ERROR_NULLSCN, _("Request error: can't manipulate null section")) +__err__(ERROR_SCNDATAMISMATCH, _("Request error: data does not belong to section")) +__err__(ERROR_NOSTRTAB, _("Request error: no string table")) +__err__(ERROR_BADSTROFF, _("Request error: string table offset out of range")) +__err__(ERROR_RDONLY, _("Request error: update(ELF_C_WRITE) on read-only file")) +__err__(ERROR_IO_SEEK, _("I/O error: seek")) +__err__(ERROR_IO_2BIG, _("I/O error: file too big for memory")) +__err__(ERROR_IO_READ, _("I/O error: raw read")) +__err__(ERROR_IO_GETSIZE, _("I/O error: get file size")) +__err__(ERROR_IO_WRITE, _("I/O error: output write")) +__err__(ERROR_IO_TRUNC, _("I/O error: can't truncate output file")) +__err__(ERROR_VERSION_UNSET, _("Sequence error: must set ELF version first")) +__err__(ERROR_NOEHDR, _("Sequence error: must create ELF header first")) +__err__(ERROR_OUTSIDE, _("Format error: reference outside file")) +__err__(ERROR_TRUNC_ARHDR, _("Format error: archive header truncated")) +__err__(ERROR_ARFMAG, _("Format error: archive fmag")) +__err__(ERROR_ARHDR, _("Format error: archive header")) +__err__(ERROR_TRUNC_MEMBER, _("Format error: archive member truncated")) +__err__(ERROR_SIZE_ARSYMTAB, _("Format error: archive symbol table size")) +__err__(ERROR_ARSTRTAB, _("Format error: archive string table")) +__err__(ERROR_ARSPECIAL, _("Format error: archive special name unknown")) +__err__(ERROR_TRUNC_EHDR, _("Format error: ELF header truncated")) +__err__(ERROR_TRUNC_PHDR, _("Format error: program header table truncated")) +__err__(ERROR_TRUNC_SHDR, _("Format error: section header table truncated")) +__err__(ERROR_TRUNC_SCN, _("Format error: data region truncated")) +__err__(ERROR_ALIGN_PHDR, _("Format error: program header table alignment")) +__err__(ERROR_ALIGN_SHDR, _("Format error: section header table alignment")) +__err__(ERROR_VERDEF_FORMAT, _("Format error: bad parameter in Verdef record")) +__err__(ERROR_VERDEF_VERSION, _("Format error: unknown Verdef version")) +__err__(ERROR_VERNEED_FORMAT, _("Format error: bad parameter in Verneed record")) +__err__(ERROR_VERNEED_VERSION, _("Format error: unknown Verneed version")) +__err__(ERROR_EHDR_SHNUM, _("Format error: bad e_shnum value")) +__err__(ERROR_EHDR_SHENTSIZE, _("Format error: bad e_shentsize value")) +__err__(ERROR_EHDR_PHENTSIZE, _("Format error: bad e_phentsize value")) +__err__(ERROR_UNTERM, _("Format error: unterminated string in string table")) +__err__(ERROR_SCN2SMALL, _("Layout error: section size too small for data")) +__err__(ERROR_SCN_OVERLAP, _("Layout error: overlapping sections")) +__err__(ERROR_MEM_ELF, _("Memory error: elf descriptor")) +__err__(ERROR_MEM_ARSYMTAB, _("Memory error: archive symbol table")) +__err__(ERROR_MEM_ARHDR, _("Memory error: archive member header")) +__err__(ERROR_MEM_EHDR, _("Memory error: ELF header")) +__err__(ERROR_MEM_PHDR, _("Memory error: program header table")) +__err__(ERROR_MEM_SHDR, _("Memory error: section header table")) +__err__(ERROR_MEM_SCN, _("Memory error: section descriptor")) +__err__(ERROR_MEM_SCNDATA, _("Memory error: section data")) +__err__(ERROR_MEM_OUTBUF, _("Memory error: output file space")) +__err__(ERROR_MEM_TEMPORARY, _("Memory error: temporary buffer")) +__err__(ERROR_BADVALUE, _("GElf error: value out of range")) +__err__(ERROR_BADINDEX, _("GElf error: index out of range")) +__err__(ERROR_BADTYPE, _("GElf error: type mismatch")) +__err__(ERROR_MEM_SYM, _("GElf error: not enough memory for GElf_Sym")) +__err__(ERROR_MEM_DYN, _("GElf error: not enough memory for GElf_Dyn")) +__err__(ERROR_MEM_RELA, _("GElf error: not enough memory for GElf_Rela")) +__err__(ERROR_MEM_REL, _("GElf error: not enough memory for GElf_Rel")) diff --git a/external/libelf/src/ext_types.h b/external/libelf/src/ext_types.h new file mode 100644 index 00000000..ead116db --- /dev/null +++ b/external/libelf/src/ext_types.h @@ -0,0 +1,334 @@ +/* +ext_types.h - external representation of ELF data types. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +/* @(#) $Id: ext_types.h,v 1.9 2008/05/23 08:15:34 michael Exp $ */ + +#ifndef _EXT_TYPES_H +#define _EXT_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Scalar data types + */ +typedef unsigned char __ext_Elf32_Addr [ELF32_FSZ_ADDR]; +typedef unsigned char __ext_Elf32_Half [ELF32_FSZ_HALF]; +typedef unsigned char __ext_Elf32_Off [ELF32_FSZ_OFF]; +typedef unsigned char __ext_Elf32_Sword [ELF32_FSZ_SWORD]; +typedef unsigned char __ext_Elf32_Word [ELF32_FSZ_WORD]; + +#if __LIBELF64 + +typedef unsigned char __ext_Elf32_Lword [8]; + +typedef unsigned char __ext_Elf64_Addr [ELF64_FSZ_ADDR]; +typedef unsigned char __ext_Elf64_Half [ELF64_FSZ_HALF]; +typedef unsigned char __ext_Elf64_Off [ELF64_FSZ_OFF]; +typedef unsigned char __ext_Elf64_Sword [ELF64_FSZ_SWORD]; +typedef unsigned char __ext_Elf64_Word [ELF64_FSZ_WORD]; +typedef unsigned char __ext_Elf64_Sxword[ELF64_FSZ_SXWORD]; +typedef unsigned char __ext_Elf64_Xword [ELF64_FSZ_XWORD]; + +typedef unsigned char __ext_Elf64_Lword [8]; + +#endif /* __LIBELF64 */ + +/* + * ELF header + */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; + __ext_Elf32_Half e_type; + __ext_Elf32_Half e_machine; + __ext_Elf32_Word e_version; + __ext_Elf32_Addr e_entry; + __ext_Elf32_Off e_phoff; + __ext_Elf32_Off e_shoff; + __ext_Elf32_Word e_flags; + __ext_Elf32_Half e_ehsize; + __ext_Elf32_Half e_phentsize; + __ext_Elf32_Half e_phnum; + __ext_Elf32_Half e_shentsize; + __ext_Elf32_Half e_shnum; + __ext_Elf32_Half e_shstrndx; +} __ext_Elf32_Ehdr; + +#if __LIBELF64 +typedef struct { + unsigned char e_ident[EI_NIDENT]; + __ext_Elf64_Half e_type; + __ext_Elf64_Half e_machine; + __ext_Elf64_Word e_version; + __ext_Elf64_Addr e_entry; + __ext_Elf64_Off e_phoff; + __ext_Elf64_Off e_shoff; + __ext_Elf64_Word e_flags; + __ext_Elf64_Half e_ehsize; + __ext_Elf64_Half e_phentsize; + __ext_Elf64_Half e_phnum; + __ext_Elf64_Half e_shentsize; + __ext_Elf64_Half e_shnum; + __ext_Elf64_Half e_shstrndx; +} __ext_Elf64_Ehdr; +#endif /* __LIBELF64 */ + +/* + * Section header + */ +typedef struct { + __ext_Elf32_Word sh_name; + __ext_Elf32_Word sh_type; + __ext_Elf32_Word sh_flags; + __ext_Elf32_Addr sh_addr; + __ext_Elf32_Off sh_offset; + __ext_Elf32_Word sh_size; + __ext_Elf32_Word sh_link; + __ext_Elf32_Word sh_info; + __ext_Elf32_Word sh_addralign; + __ext_Elf32_Word sh_entsize; +} __ext_Elf32_Shdr; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word sh_name; + __ext_Elf64_Word sh_type; + __ext_Elf64_Xword sh_flags; + __ext_Elf64_Addr sh_addr; + __ext_Elf64_Off sh_offset; + __ext_Elf64_Xword sh_size; + __ext_Elf64_Word sh_link; + __ext_Elf64_Word sh_info; + __ext_Elf64_Xword sh_addralign; + __ext_Elf64_Xword sh_entsize; +} __ext_Elf64_Shdr; +#endif /* __LIBELF64 */ + +/* + * Symbol table + */ +typedef struct { + __ext_Elf32_Word st_name; + __ext_Elf32_Addr st_value; + __ext_Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + __ext_Elf32_Half st_shndx; +} __ext_Elf32_Sym; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + __ext_Elf64_Half st_shndx; + __ext_Elf64_Addr st_value; + __ext_Elf64_Xword st_size; +} __ext_Elf64_Sym; +#endif /* __LIBELF64 */ + +/* + * Relocation + */ +typedef struct { + __ext_Elf32_Addr r_offset; + __ext_Elf32_Word r_info; +} __ext_Elf32_Rel; + +typedef struct { + __ext_Elf32_Addr r_offset; + __ext_Elf32_Word r_info; + __ext_Elf32_Sword r_addend; +} __ext_Elf32_Rela; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Addr r_offset; +#if __LIBELF64_IRIX + __ext_Elf64_Word r_sym; + unsigned char r_ssym; + unsigned char r_type3; + unsigned char r_type2; + unsigned char r_type; +#else /* __LIBELF64_IRIX */ + __ext_Elf64_Xword r_info; +#endif /* __LIBELF64_IRIX */ +} __ext_Elf64_Rel; + +typedef struct { + __ext_Elf64_Addr r_offset; +#if __LIBELF64_IRIX + __ext_Elf64_Word r_sym; + unsigned char r_ssym; + unsigned char r_type3; + unsigned char r_type2; + unsigned char r_type; +#else /* __LIBELF64_IRIX */ + __ext_Elf64_Xword r_info; +#endif /* __LIBELF64_IRIX */ + __ext_Elf64_Sxword r_addend; +} __ext_Elf64_Rela; +#endif /* __LIBELF64 */ + +/* + * Program header + */ +typedef struct { + __ext_Elf32_Word p_type; + __ext_Elf32_Off p_offset; + __ext_Elf32_Addr p_vaddr; + __ext_Elf32_Addr p_paddr; + __ext_Elf32_Word p_filesz; + __ext_Elf32_Word p_memsz; + __ext_Elf32_Word p_flags; + __ext_Elf32_Word p_align; +} __ext_Elf32_Phdr; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Word p_type; + __ext_Elf64_Word p_flags; + __ext_Elf64_Off p_offset; + __ext_Elf64_Addr p_vaddr; + __ext_Elf64_Addr p_paddr; + __ext_Elf64_Xword p_filesz; + __ext_Elf64_Xword p_memsz; + __ext_Elf64_Xword p_align; +} __ext_Elf64_Phdr; +#endif /* __LIBELF64 */ + +/* + * Dynamic structure + */ +typedef struct { + __ext_Elf32_Sword d_tag; + union { + __ext_Elf32_Word d_val; + __ext_Elf32_Addr d_ptr; + } d_un; +} __ext_Elf32_Dyn; + +#if __LIBELF64 +typedef struct { + __ext_Elf64_Sxword d_tag; + union { + __ext_Elf64_Xword d_val; + __ext_Elf64_Addr d_ptr; + } d_un; +} __ext_Elf64_Dyn; +#endif /* __LIBELF64 */ + +/* + * Version definitions + */ +typedef struct { + __ext_Elf32_Half vd_version; + __ext_Elf32_Half vd_flags; + __ext_Elf32_Half vd_ndx; + __ext_Elf32_Half vd_cnt; + __ext_Elf32_Word vd_hash; + __ext_Elf32_Word vd_aux; + __ext_Elf32_Word vd_next; +} __ext_Elf32_Verdef; + +typedef struct { + __ext_Elf32_Word vda_name; + __ext_Elf32_Word vda_next; +} __ext_Elf32_Verdaux; + +typedef struct { + __ext_Elf32_Half vn_version; + __ext_Elf32_Half vn_cnt; + __ext_Elf32_Word vn_file; + __ext_Elf32_Word vn_aux; + __ext_Elf32_Word vn_next; +} __ext_Elf32_Verneed; + +typedef struct { + __ext_Elf32_Word vna_hash; + __ext_Elf32_Half vna_flags; + __ext_Elf32_Half vna_other; + __ext_Elf32_Word vna_name; + __ext_Elf32_Word vna_next; +} __ext_Elf32_Vernaux; + +#if __LIBELF64 + +typedef struct { + __ext_Elf64_Half vd_version; + __ext_Elf64_Half vd_flags; + __ext_Elf64_Half vd_ndx; + __ext_Elf64_Half vd_cnt; + __ext_Elf64_Word vd_hash; + __ext_Elf64_Word vd_aux; + __ext_Elf64_Word vd_next; +} __ext_Elf64_Verdef; + +typedef struct { + __ext_Elf64_Word vda_name; + __ext_Elf64_Word vda_next; +} __ext_Elf64_Verdaux; + +typedef struct { + __ext_Elf64_Half vn_version; + __ext_Elf64_Half vn_cnt; + __ext_Elf64_Word vn_file; + __ext_Elf64_Word vn_aux; + __ext_Elf64_Word vn_next; +} __ext_Elf64_Verneed; + +typedef struct { + __ext_Elf64_Word vna_hash; + __ext_Elf64_Half vna_flags; + __ext_Elf64_Half vna_other; + __ext_Elf64_Word vna_name; + __ext_Elf64_Word vna_next; +} __ext_Elf64_Vernaux; + +#endif /* __LIBELF64 */ + +/* + * Move section + */ +#if __LIBELF64 + +typedef struct { + __ext_Elf32_Lword m_value; + __ext_Elf32_Word m_info; + __ext_Elf32_Word m_poffset; + __ext_Elf32_Half m_repeat; + __ext_Elf32_Half m_stride; +} __ext_Elf32_Move; + +typedef struct { + __ext_Elf64_Lword m_value; + __ext_Elf64_Xword m_info; + __ext_Elf64_Xword m_poffset; + __ext_Elf64_Half m_repeat; + __ext_Elf64_Half m_stride; +} __ext_Elf64_Move; + +#endif /* __LIBELF64 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _EXT_TYPES_H */ diff --git a/external/libelf/src/fill.c b/external/libelf/src/fill.c new file mode 100644 index 00000000..e64cc141 --- /dev/null +++ b/external/libelf/src/fill.c @@ -0,0 +1,29 @@ +/* +fill.c - implementation of the elf_fill(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: fill.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +void +elf_fill(int fill) { + _elf_fill = fill; +} diff --git a/external/libelf/src/flag.c b/external/libelf/src/flag.c new file mode 100644 index 00000000..1845ff94 --- /dev/null +++ b/external/libelf/src/flag.c @@ -0,0 +1,92 @@ +/* +flag.c - implementation of the elf_flag*(3) functions. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: flag.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +static unsigned +_elf_flag(unsigned *f, Elf_Cmd cmd, unsigned flags) { + if (cmd == ELF_C_SET) { + return *f |= flags; + } + if (cmd == ELF_C_CLR) { + return *f &= ~flags; + } + seterr(ERROR_INVALID_CMD); + return 0; +} + +unsigned +elf_flagdata(Elf_Data *data, Elf_Cmd cmd, unsigned flags) { + Scn_Data *sd = (Scn_Data*)data; + + if (!sd) { + return 0; + } + elf_assert(sd->sd_magic == DATA_MAGIC); + return _elf_flag(&sd->sd_data_flags, cmd, flags); +} + +unsigned +elf_flagehdr(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_ehdr_flags, cmd, flags); +} + +unsigned +elf_flagelf(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_elf_flags, cmd, flags); +} + +unsigned +elf_flagphdr(Elf *elf, Elf_Cmd cmd, unsigned flags) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return _elf_flag(&elf->e_phdr_flags, cmd, flags); +} + +unsigned +elf_flagscn(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) { + if (!scn) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return _elf_flag(&scn->s_scn_flags, cmd, flags); +} + +unsigned +elf_flagshdr(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) { + if (!scn) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return _elf_flag(&scn->s_shdr_flags, cmd, flags); +} diff --git a/external/libelf/src/gelf.h b/external/libelf/src/gelf.h new file mode 100644 index 00000000..5af05589 --- /dev/null +++ b/external/libelf/src/gelf.h @@ -0,0 +1,155 @@ +/* + * gelf.h - public header file for libelf. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: gelf.h,v 1.16 2008/05/23 08:15:34 michael Exp $ */ + +#ifndef _GELF_H +#define _GELF_H + +#if __LIBELF_INTERNAL__ +#include +#else /* __LIBELF_INTERNAL__ */ +#include +#endif /* __LIBELF_INTERNAL__ */ + +#if __LIBELF_NEED_LINK_H +#include +#elif __LIBELF_NEED_SYS_LINK_H +#include +#endif /* __LIBELF_NEED_LINK_H */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef __P +# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +# define __P(args) args +# else /* __STDC__ || defined(__cplusplus) */ +# define __P(args) () +# endif /* __STDC__ || defined(__cplusplus) */ +#endif /* __P */ + +#if !__LIBELF64 + +#error "GElf is not supported on this system." + +#else /* __LIBELF64 */ + +typedef Elf64_Addr GElf_Addr; +typedef Elf64_Half GElf_Half; +typedef Elf64_Off GElf_Off; +typedef Elf64_Sword GElf_Sword; +typedef Elf64_Word GElf_Word; +typedef Elf64_Sxword GElf_Sxword; +typedef Elf64_Xword GElf_Xword; + +typedef Elf64_Ehdr GElf_Ehdr; +typedef Elf64_Phdr GElf_Phdr; +typedef Elf64_Shdr GElf_Shdr; +typedef Elf64_Dyn GElf_Dyn; +typedef Elf64_Rel GElf_Rel; +typedef Elf64_Rela GElf_Rela; +typedef Elf64_Sym GElf_Sym; + +/* + * Symbol versioning + */ +#if __LIBELF_SYMBOL_VERSIONS +typedef Elf64_Verdef GElf_Verdef; +typedef Elf64_Verneed GElf_Verneed; +typedef Elf64_Verdaux GElf_Verdaux; +typedef Elf64_Vernaux GElf_Vernaux; +#endif /* __LIBELF_SYMBOL_VERSIONS */ + +/* + * These types aren't implemented (yet) + * +typedef Elf64_Move GElf_Move; +typedef Elf64_Syminfo GElf_Syminfo; + */ + +/* + * Generic macros + */ +#define GELF_ST_BIND ELF64_ST_BIND +#define GELF_ST_TYPE ELF64_ST_TYPE +#define GELF_ST_INFO ELF64_ST_INFO + +#define GELF_R_TYPE ELF64_R_TYPE +#define GELF_R_SYM ELF64_R_SYM +#define GELF_R_INFO ELF64_R_INFO + +/* + * Function declarations + */ +extern int gelf_getclass __P((Elf *__elf)); + +extern size_t gelf_fsize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver)); + +extern Elf_Data *gelf_xlatetof __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode)); +extern Elf_Data *gelf_xlatetom __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode)); + +extern GElf_Ehdr *gelf_getehdr __P((Elf *__elf, GElf_Ehdr *__dst)); +extern int gelf_update_ehdr __P((Elf *__elf, GElf_Ehdr *__src)); +extern unsigned long gelf_newehdr __P((Elf *__elf, int __elfclass)); + +extern GElf_Phdr *gelf_getphdr __P((Elf *__elf, int ndx, GElf_Phdr *__dst)); +extern int gelf_update_phdr __P((Elf *__elf, int ndx, GElf_Phdr *__src)); +extern unsigned long gelf_newphdr __P((Elf *__elf, size_t __phnum)); + +extern GElf_Shdr *gelf_getshdr __P((Elf_Scn *__scn, GElf_Shdr *__dst)); +extern int gelf_update_shdr __P((Elf_Scn *__scn, GElf_Shdr *__src)); + +extern GElf_Dyn *gelf_getdyn __P((Elf_Data *__src, int __ndx, GElf_Dyn *__dst)); +extern int gelf_update_dyn __P((Elf_Data *__dst, int __ndx, GElf_Dyn *__src)); + +extern GElf_Rel *gelf_getrel __P((Elf_Data *__src, int __ndx, GElf_Rel *__dst)); +extern int gelf_update_rel __P((Elf_Data *__dst, int __ndx, GElf_Rel *__src)); + +extern GElf_Rela *gelf_getrela __P((Elf_Data *__src, int __ndx, GElf_Rela *__dst)); +extern int gelf_update_rela __P((Elf_Data *__dst, int __ndx, GElf_Rela *__src)); + +extern GElf_Sym *gelf_getsym __P((Elf_Data *__src, int __ndx, GElf_Sym *__dst)); +extern int gelf_update_sym __P((Elf_Data *__dst, int __ndx, GElf_Sym *__src)); + +extern long gelf_checksum __P((Elf *__elf)); + +/* + * These functions aren't implemented (yet) + * +extern GElf_Move *gelf_getmove __P((Elf_Data *__src, int __ndx, GElf_Move *__src)); +extern int gelf_update_move __P((Elf_Data *__dst, int __ndx, GElf_Move *__src)); + * +extern GElf_Syminfo* gelf_getsyminfo __P((Elf_Data *__src, int __ndx, GElf_Syminfo *__dst)); +extern int gelf_update_syminfo __P((Elf_Data *__dst, int __ndx, GElf_Syminfo *__src)); + */ + +/* + * Extensions (not available in other versions of libelf) + */ +extern size_t gelf_msize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver)); + +#endif /* __LIBELF64 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GELF_H */ diff --git a/external/libelf/src/gelfehdr.c b/external/libelf/src/gelfehdr.c new file mode 100644 index 00000000..fa7c0191 --- /dev/null +++ b/external/libelf/src/gelfehdr.c @@ -0,0 +1,140 @@ +/* + * gelfehdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfehdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Ehdr* +gelf_getehdr(Elf *elf, GElf_Ehdr *dst) { + GElf_Ehdr buf; + char *tmp; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getehdr(elf, elf->e_class); + if (!tmp) { + return NULL; + } + if (!dst) { + dst = &buf; + } + if (elf->e_class == ELFCLASS64) { + *dst = *(Elf64_Ehdr*)tmp; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Ehdr *src = (Elf32_Ehdr*)tmp; + + memcpy(dst->e_ident, src->e_ident, EI_NIDENT); + check_and_copy(GElf_Half, dst, src, e_type, NULL); + check_and_copy(GElf_Half, dst, src, e_machine, NULL); + check_and_copy(GElf_Word, dst, src, e_version, NULL); + check_and_copy(GElf_Addr, dst, src, e_entry, NULL); + check_and_copy(GElf_Off, dst, src, e_phoff, NULL); + check_and_copy(GElf_Off, dst, src, e_shoff, NULL); + check_and_copy(GElf_Word, dst, src, e_flags, NULL); + check_and_copy(GElf_Half, dst, src, e_ehsize, NULL); + check_and_copy(GElf_Half, dst, src, e_phentsize, NULL); + check_and_copy(GElf_Half, dst, src, e_phnum, NULL); + check_and_copy(GElf_Half, dst, src, e_shentsize, NULL); + check_and_copy(GElf_Half, dst, src, e_shnum, NULL); + check_and_copy(GElf_Half, dst, src, e_shstrndx, NULL); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Ehdr*)malloc(sizeof(GElf_Ehdr)); + if (!dst) { + seterr(ERROR_MEM_EHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) { + char *tmp; + + if (!elf || !src) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getehdr(elf, elf->e_class); + if (!tmp) { + return 0; + } + if (elf->e_class == ELFCLASS64) { + *(Elf64_Ehdr*)tmp = *src; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Ehdr *dst = (Elf32_Ehdr*)tmp; + + memcpy(dst->e_ident, src->e_ident, EI_NIDENT); + check_and_copy(Elf32_Half, dst, src, e_type, 0); + check_and_copy(Elf32_Half, dst, src, e_machine, 0); + check_and_copy(Elf32_Word, dst, src, e_version, 0); + check_and_copy(Elf32_Addr, dst, src, e_entry, 0); + check_and_copy(Elf32_Off, dst, src, e_phoff, 0); + check_and_copy(Elf32_Off, dst, src, e_shoff, 0); + check_and_copy(Elf32_Word, dst, src, e_flags, 0); + check_and_copy(Elf32_Half, dst, src, e_ehsize, 0); + check_and_copy(Elf32_Half, dst, src, e_phentsize, 0); + check_and_copy(Elf32_Half, dst, src, e_phnum, 0); + check_and_copy(Elf32_Half, dst, src, e_shentsize, 0); + check_and_copy(Elf32_Half, dst, src, e_shnum, 0); + check_and_copy(Elf32_Half, dst, src, e_shstrndx, 0); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/gelfphdr.c b/external/libelf/src/gelfphdr.c new file mode 100644 index 00000000..2635b4ac --- /dev/null +++ b/external/libelf/src/gelfphdr.c @@ -0,0 +1,148 @@ +/* + * gelfphdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfphdr.c,v 1.9 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Phdr* +gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) { + GElf_Phdr buf; + char *tmp; + size_t n; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getphdr(elf, elf->e_class); + if (!tmp) { + return NULL; + } + if (ndx < 0 || ndx >= elf->e_phnum) { + seterr(ERROR_BADINDEX); + return NULL; + } + n = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (!dst) { + dst = &buf; + } + if (elf->e_class == ELFCLASS64) { + *dst = *(Elf64_Phdr*)(tmp + ndx * n); + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Phdr *src = (Elf32_Phdr*)(tmp + ndx * n); + + check_and_copy(GElf_Word, dst, src, p_type, NULL); + check_and_copy(GElf_Word, dst, src, p_flags, NULL); + check_and_copy(GElf_Off, dst, src, p_offset, NULL); + check_and_copy(GElf_Addr, dst, src, p_vaddr, NULL); + check_and_copy(GElf_Addr, dst, src, p_paddr, NULL); + check_and_copy(GElf_Xword, dst, src, p_filesz, NULL); + check_and_copy(GElf_Xword, dst, src, p_memsz, NULL); + check_and_copy(GElf_Xword, dst, src, p_align, NULL); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Phdr*)malloc(sizeof(GElf_Phdr)); + if (!dst) { + seterr(ERROR_MEM_PHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) { + char *tmp; + size_t n; + + if (!elf || !src) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + tmp = _elf_getphdr(elf, elf->e_class); + if (!tmp) { + return 0; + } + if (ndx < 0 || ndx >= elf->e_phnum) { + seterr(ERROR_BADINDEX); + return 0; + } + n = _msize(elf->e_class, _elf_version, ELF_T_PHDR); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + if (elf->e_class == ELFCLASS64) { + *(Elf64_Phdr*)(tmp + ndx * n) = *src; + } + else if (elf->e_class == ELFCLASS32) { + Elf32_Phdr *dst = (Elf32_Phdr*)(tmp + ndx * n); + + check_and_copy(Elf32_Word, dst, src, p_type, 0); + check_and_copy(Elf32_Off, dst, src, p_offset, 0); + check_and_copy(Elf32_Addr, dst, src, p_vaddr, 0); + check_and_copy(Elf32_Addr, dst, src, p_paddr, 0); + check_and_copy(Elf32_Word, dst, src, p_filesz, 0); + check_and_copy(Elf32_Word, dst, src, p_memsz, 0); + check_and_copy(Elf32_Word, dst, src, p_flags, 0); + check_and_copy(Elf32_Word, dst, src, p_align, 0); + } + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/gelfshdr.c b/external/libelf/src/gelfshdr.c new file mode 100644 index 00000000..c295c187 --- /dev/null +++ b/external/libelf/src/gelfshdr.c @@ -0,0 +1,125 @@ +/* + * gelfshdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.10 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +GElf_Shdr* +gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) { + GElf_Shdr buf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (!dst) { + dst = &buf; + } + if (scn->s_elf->e_class == ELFCLASS64) { + *dst = scn->s_shdr64; + } + else if (scn->s_elf->e_class == ELFCLASS32) { + Elf32_Shdr *src = &scn->s_shdr32; + + check_and_copy(GElf_Word, dst, src, sh_name, NULL); + check_and_copy(GElf_Word, dst, src, sh_type, NULL); + check_and_copy(GElf_Xword, dst, src, sh_flags, NULL); + check_and_copy(GElf_Addr, dst, src, sh_addr, NULL); + check_and_copy(GElf_Off, dst, src, sh_offset, NULL); + check_and_copy(GElf_Xword, dst, src, sh_size, NULL); + check_and_copy(GElf_Word, dst, src, sh_link, NULL); + check_and_copy(GElf_Word, dst, src, sh_info, NULL); + check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL); + check_and_copy(GElf_Xword, dst, src, sh_entsize, NULL); + } + else { + if (valid_class(scn->s_elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return NULL; + } + if (dst == &buf) { + dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr)); + if (!dst) { + seterr(ERROR_MEM_SHDR); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) { + if (!scn || !src) { + return 0; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf); + elf_assert(scn->s_elf->e_magic == ELF_MAGIC); + if (scn->s_elf->e_class == ELFCLASS64) { + scn->s_shdr64 = *src; + } + else if (scn->s_elf->e_class == ELFCLASS32) { + Elf32_Shdr *dst = &scn->s_shdr32; + + check_and_copy(Elf32_Word, dst, src, sh_name, 0); + check_and_copy(Elf32_Word, dst, src, sh_type, 0); + check_and_copy(Elf32_Word, dst, src, sh_flags, 0); + check_and_copy(Elf32_Addr, dst, src, sh_addr, 0); + check_and_copy(Elf32_Off, dst, src, sh_offset, 0); + check_and_copy(Elf32_Word, dst, src, sh_size, 0); + check_and_copy(Elf32_Word, dst, src, sh_link, 0); + check_and_copy(Elf32_Word, dst, src, sh_info, 0); + check_and_copy(Elf32_Word, dst, src, sh_addralign, 0); + check_and_copy(Elf32_Word, dst, src, sh_entsize, 0); + } + else { + if (valid_class(scn->s_elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/gelftrans.c b/external/libelf/src/gelftrans.c new file mode 100644 index 00000000..dcd0cdd3 --- /dev/null +++ b/external/libelf/src/gelftrans.c @@ -0,0 +1,407 @@ +/* +gelftrans.c - gelf_* translation functions. +Copyright (C) 2000 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelftrans.c,v 1.10 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (0) + +/* + * These macros are missing on some Linux systems + */ +#if !defined(ELF32_R_SYM) || !defined(ELF32_R_TYPE) || !defined(ELF32_R_INFO) +# undef ELF32_R_SYM +# undef ELF32_R_TYPE +# undef ELF32_R_INFO +# define ELF32_R_SYM(i) ((i)>>8) +# define ELF32_R_TYPE(i) ((unsigned char)(i)) +# define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) +#endif /* !defined(...) */ + +#if !defined(ELF64_R_SYM) || !defined(ELF64_R_TYPE) || !defined(ELF64_R_INFO) +# undef ELF64_R_SYM +# undef ELF64_R_TYPE +# undef ELF64_R_INFO +# define ELF64_R_SYM(i) ((i)>>32) +# define ELF64_R_TYPE(i) ((i)&0xffffffffL) +# define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+((t)&0xffffffffL)) +#endif /* !defined(...) */ + +static char* +get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) { + Scn_Data *sd = (Scn_Data*)data; + Elf_Scn *scn; + Elf *elf; + size_t n; + + if (!sd) { + return NULL; + } + elf_assert(sd->sd_magic == DATA_MAGIC); + scn = sd->sd_scn; + elf_assert(scn); + elf_assert(scn->s_magic == SCN_MAGIC); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return NULL; + } + if (!valid_class(elf->e_class)) { + seterr(ERROR_UNKNOWN_CLASS); + return NULL; + } + if (data->d_type != type) { + seterr(ERROR_BADTYPE); + return NULL; + } + n = _msize(elf->e_class, data->d_version, type); + if (n == 0) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (ndx < 0 || data->d_size < (ndx + 1) * n) { + seterr(ERROR_BADINDEX); + return NULL; + } + if (!data->d_buf) { + seterr(ERROR_NULLBUF); + return NULL; + } + if (cls) { + *cls = elf->e_class; + } + return (char*)data->d_buf + n * ndx; +} + +GElf_Sym* +gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) { + GElf_Sym buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Sym*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Sym *src = (Elf32_Sym*)tmp; + + check_and_copy(GElf_Word, dst, src, st_name, NULL); + check_and_copy(unsigned char, dst, src, st_info, NULL); + check_and_copy(unsigned char, dst, src, st_other, NULL); + check_and_copy(GElf_Half, dst, src, st_shndx, NULL); + check_and_copy(GElf_Addr, dst, src, st_value, NULL); + check_and_copy(GElf_Xword, dst, src, st_size, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Sym*)malloc(sizeof(GElf_Sym)); + if (!dst) { + seterr(ERROR_MEM_SYM); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Sym*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Sym *dst = (Elf32_Sym*)tmp; + + check_and_copy(Elf32_Word, dst, src, st_name, 0); + check_and_copy(Elf32_Addr, dst, src, st_value, 0); + check_and_copy(Elf32_Word, dst, src, st_size, 0); + check_and_copy(unsigned char, dst, src, st_info, 0); + check_and_copy(unsigned char, dst, src, st_other, 0); + check_and_copy(Elf32_Half, dst, src, st_shndx, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Dyn* +gelf_getdyn(Elf_Data *src, int ndx, GElf_Dyn *dst) { + GElf_Dyn buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_DYN, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Dyn*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Dyn *src = (Elf32_Dyn*)tmp; + + check_and_copy(GElf_Sxword, dst, src, d_tag, NULL); + check_and_copy(GElf_Xword, dst, src, d_un.d_val, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Dyn*)malloc(sizeof(GElf_Dyn)); + if (!dst) { + seterr(ERROR_MEM_DYN); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_DYN, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Dyn*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Dyn *dst = (Elf32_Dyn*)tmp; + + check_and_copy(Elf32_Sword, dst, src, d_tag, 0); + check_and_copy(Elf32_Word, dst, src, d_un.d_val, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Rela* +gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) { + GElf_Rela buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_RELA, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Rela*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Rela *src = (Elf32_Rela*)tmp; + + check_and_copy(GElf_Addr, dst, src, r_offset, NULL); + dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info), + (Elf64_Xword)ELF32_R_TYPE(src->r_info)); + check_and_copy(GElf_Sxword, dst, src, r_addend, NULL); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Rela*)malloc(sizeof(GElf_Rela)); + if (!dst) { + seterr(ERROR_MEM_RELA); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_RELA, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Rela*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Rela *dst = (Elf32_Rela*)tmp; + + check_and_copy(Elf32_Addr, dst, src, r_offset, 0); + if (ELF64_R_SYM(src->r_info) > 0xffffffUL + || ELF64_R_TYPE(src->r_info) > 0xffUL) { + seterr(ERROR_BADVALUE); + return 0; + } + dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info), + (Elf32_Word)ELF64_R_TYPE(src->r_info)); + check_and_copy(Elf32_Sword, dst, src, r_addend, 0); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +GElf_Rel* +gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) { + GElf_Rel buf; + unsigned cls; + char *tmp; + + if (!dst) { + dst = &buf; + } + tmp = get_addr_and_class(src, ndx, ELF_T_REL, &cls); + if (!tmp) { + return NULL; + } + if (cls == ELFCLASS64) { + *dst = *(Elf64_Rel*)tmp; + } + else if (cls == ELFCLASS32) { + Elf32_Rel *src = (Elf32_Rel*)tmp; + + check_and_copy(GElf_Addr, dst, src, r_offset, NULL); + dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info), + (Elf64_Xword)ELF32_R_TYPE(src->r_info)); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dst == &buf) { + dst = (GElf_Rel*)malloc(sizeof(GElf_Rel)); + if (!dst) { + seterr(ERROR_MEM_REL); + return NULL; + } + *dst = buf; + } + return dst; +} + +int +gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) { + unsigned cls; + char *tmp; + + tmp = get_addr_and_class(dst, ndx, ELF_T_REL, &cls); + if (!tmp) { + return 0; + } + if (cls == ELFCLASS64) { + *(Elf64_Rel*)tmp = *src; + } + else if (cls == ELFCLASS32) { + Elf32_Rel *dst = (Elf32_Rel*)tmp; + + check_and_copy(Elf32_Addr, dst, src, r_offset, 0); + if (ELF64_R_SYM(src->r_info) > 0xffffffUL + || ELF64_R_TYPE(src->r_info) > 0xffUL) { + seterr(ERROR_BADVALUE); + return 0; + } + dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info), + (Elf32_Word)ELF64_R_TYPE(src->r_info)); + } + else { + seterr(ERROR_UNIMPLEMENTED); + return 0; + } + return 1; +} + +#if 0 + +GElf_Syminfo* +gelf_getsyminfo(Elf_Data *src, int ndx, GElf_Syminfo *dst) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +int +gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) { + seterr(ERROR_UNIMPLEMENTED); + return 0; +} + +GElf_Move* +gelf_getmove(Elf_Data *src, int ndx, GElf_Move *src) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; +} + +int +gelf_update_move(Elf_Data *dst, int ndx, GElf_Move *src) { + seterr(ERROR_UNIMPLEMENTED); + return 0; +} + +#endif + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/getarhdr.c b/external/libelf/src/getarhdr.c new file mode 100644 index 00000000..874b337e --- /dev/null +++ b/external/libelf/src/getarhdr.c @@ -0,0 +1,37 @@ +/* +getarhdr.c - implementation of the elf_getarhdr(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getarhdr.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +Elf_Arhdr* +elf_getarhdr(Elf *elf) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_arhdr) { + return elf->e_arhdr; + } + seterr(ERROR_NOTARCHIVE); + return NULL; +} diff --git a/external/libelf/src/getaroff.c b/external/libelf/src/getaroff.c new file mode 100644 index 00000000..fce977d9 --- /dev/null +++ b/external/libelf/src/getaroff.c @@ -0,0 +1,40 @@ +/* + * getaroff.c - implementation of the elf_getaroff(3) function. + * Copyright (C) 2009 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getaroff.c,v 1.1 2009/11/01 13:04:19 michael Exp $"; +#endif /* lint */ + +off_t +elf_getaroff(Elf *elf) { + Elf *ref; + + if (!elf) { + return (off_t)-1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!(ref = elf->e_parent)) { + return (off_t)-1; + } + elf_assert(ref->e_magic == ELF_MAGIC); + elf_assert(elf->e_base >= ref->e_base + SARMAG + sizeof(struct ar_hdr)); + return (off_t)(elf->e_base - ref->e_base - sizeof(struct ar_hdr)); +} diff --git a/external/libelf/src/getarsym.c b/external/libelf/src/getarsym.c new file mode 100644 index 00000000..60696764 --- /dev/null +++ b/external/libelf/src/getarsym.c @@ -0,0 +1,87 @@ +/* + * getarsym.c - implementation of the elf_getarsym(3) function. + * Copyright (C) 1995 - 1998, 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getarsym.c,v 1.9 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +Elf_Arsym* +elf_getarsym(Elf *elf, size_t *ptr) { + Elf_Arsym *syms; + size_t count; + size_t tmp; + size_t i; + char *s; + char *e; + + if (!ptr) { + ptr = &tmp; + } + *ptr = 0; + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_AR) { + seterr(ERROR_NOTARCHIVE); + return NULL; + } + if (elf->e_symtab && !elf->e_free_syms) { + if (elf->e_symlen < 4) { + seterr(ERROR_SIZE_ARSYMTAB); + return NULL; + } + count = __load_u32M(elf->e_symtab); + if (elf->e_symlen < 4 * (count + 1)) { + seterr(ERROR_SIZE_ARSYMTAB); + return NULL; + } + if (!(syms = (Elf_Arsym*)malloc((count + 1) * sizeof(*syms)))) { + seterr(ERROR_MEM_ARSYMTAB); + return NULL; + } + s = elf->e_symtab + 4 * (count + 1); + e = elf->e_symtab + elf->e_symlen; + for (i = 0; i < count; i++, s++) { + syms[i].as_name = s; + while (s < e && *s) { + s++; + } + if (s >= e) { + seterr(ERROR_SIZE_ARSYMTAB); + free(syms); + return NULL; + } + elf_assert(!*s); + syms[i].as_hash = elf_hash((unsigned char*)syms[i].as_name); + syms[i].as_off = __load_u32M(elf->e_symtab + 4 * (i + 1)); + } + syms[count].as_name = NULL; + syms[count].as_hash = ~0UL; + syms[count].as_off = 0; + elf->e_symtab = (char*)syms; + elf->e_symlen = count + 1; + elf->e_free_syms = 1; + } + *ptr = elf->e_symlen; + return (Elf_Arsym*)elf->e_symtab; +} diff --git a/external/libelf/src/getbase.c b/external/libelf/src/getbase.c new file mode 100644 index 00000000..6831629b --- /dev/null +++ b/external/libelf/src/getbase.c @@ -0,0 +1,33 @@ +/* +getbase.c - implementation of the elf_getbase(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getbase.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +off_t +elf_getbase(Elf *elf) { + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return (off_t)elf->e_base; +} diff --git a/external/libelf/src/getdata.c b/external/libelf/src/getdata.c new file mode 100644 index 00000000..a65b7aae --- /dev/null +++ b/external/libelf/src/getdata.c @@ -0,0 +1,157 @@ +/* +getdata.c - implementation of the elf_getdata(3) function. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getdata.c,v 1.13 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +static Elf_Data* +_elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) { + Elf_Data dst; + Elf_Data src; + int flag = 0; + size_t dlen; + + elf_assert(elf->e_data); + + /* + * Prepare source + */ + src = sd->sd_data; + src.d_version = elf->e_version; + if (elf->e_rawdata) { + src.d_buf = elf->e_rawdata + scn->s_offset; + } + else { + src.d_buf = elf->e_data + scn->s_offset; + } + + /* + * Prepare destination (needs prepared source!) + */ + dst = sd->sd_data; + if (elf->e_class == ELFCLASS32) { + dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0); + } +#endif /* __LIBELF64 */ + else { + elf_assert(valid_class(elf->e_class)); + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + if (dlen == (size_t)-1) { + return NULL; + } + dst.d_size = dlen; + if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) { + dst.d_buf = elf->e_data + scn->s_offset; + } + else if (!(dst.d_buf = malloc(dst.d_size))) { + seterr(ERROR_MEM_SCNDATA); + return NULL; + } + else { + flag = 1; + } + + /* + * Translate data + */ + if (_elf_xlatetom(elf, &dst, &src)) { + sd->sd_memdata = (char*)dst.d_buf; + sd->sd_data = dst; + if (!(sd->sd_free_data = flag)) { + elf->e_cooked = 1; + } + return &sd->sd_data; + } + + if (flag) { + free(dst.d_buf); + } + return NULL; +} + +Elf_Data* +elf_getdata(Elf_Scn *scn, Elf_Data *data) { + Scn_Data *sd; + Elf *elf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NULLSCN); + } + else if (data) { + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (data == &sd->sd_data) { + /* + * sd_link allocated by elf_newdata(). + */ + return &sd->sd_link->sd_data; + } + } + seterr(ERROR_SCNDATAMISMATCH); + } + else if ((sd = scn->s_data_1)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (sd->sd_freeme) { + /* allocated by elf_newdata() */ + return &sd->sd_data; + } + else if (scn->s_type == SHT_NULL) { + seterr(ERROR_NULLSCN); + } + else if (sd->sd_memdata) { + /* already cooked */ + return &sd->sd_data; + } + else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) { + seterr(ERROR_OUTSIDE); + } + else if (scn->s_type == SHT_NOBITS || !scn->s_size) { + /* no data to read */ + return &sd->sd_data; + } + else if (scn->s_offset + scn->s_size > elf->e_size) { + seterr(ERROR_TRUNC_SCN); + } + else if (valid_class(elf->e_class)) { + return _elf_cook_scn(elf, scn, sd); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + } + return NULL; +} diff --git a/external/libelf/src/getident.c b/external/libelf/src/getident.c new file mode 100644 index 00000000..d9758f4c --- /dev/null +++ b/external/libelf/src/getident.c @@ -0,0 +1,48 @@ +/* +getident.c - implementation of the elf_getident(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getident.c,v 1.7 2008/05/23 08:15:34 michael Exp $"; +#endif /* lint */ + +char* +elf_getident(Elf *elf, size_t *ptr) { + size_t tmp; + + if (!ptr) { + ptr = &tmp; + } + if (!elf) { + *ptr = 0; + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + *ptr = elf->e_idlen; + return elf->e_data; + } + if (elf->e_ehdr || _elf_cook(elf)) { + *ptr = elf->e_idlen; + return elf->e_ehdr; + } + *ptr = 0; + return NULL; +} diff --git a/external/libelf/src/getscn.c b/external/libelf/src/getscn.c new file mode 100644 index 00000000..a78eae9f --- /dev/null +++ b/external/libelf/src/getscn.c @@ -0,0 +1,48 @@ +/* +getscn.c - implementation of the elf_getscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: getscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Scn* +elf_getscn(Elf *elf, size_t index) { + Elf_Scn *scn; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if (scn->s_index == index) { + return scn; + } + } + seterr(ERROR_NOSUCHSCN); + } + return NULL; +} diff --git a/external/libelf/src/hash.c b/external/libelf/src/hash.c new file mode 100644 index 00000000..a2555b65 --- /dev/null +++ b/external/libelf/src/hash.c @@ -0,0 +1,38 @@ +/* +hash.c - implementation of the elf_hash(3) function. +Copyright (C) 1995 - 2002 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: hash.c,v 1.10 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +unsigned long +elf_hash(const unsigned char *name) { + unsigned long hash = 0; + unsigned long tmp; + + while (*name) { + hash = (hash << 4) + (unsigned char)*name++; + if ((tmp = hash & 0xf0000000)) { + hash ^= tmp | (tmp >> 24); + } + } + return hash; +} diff --git a/external/libelf/src/input.c b/external/libelf/src/input.c new file mode 100644 index 00000000..751970a7 --- /dev/null +++ b/external/libelf/src/input.c @@ -0,0 +1,106 @@ +/* + * input.c - low-level input for libelf. + * Copyright (C) 1995 - 2001, 2005 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: input.c,v 1.11 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static int +xread(int fd, char *buffer, size_t len) { + size_t done = 0; + size_t n; + + while (done < len) { + n = read(fd, buffer + done, len - done); + if (n == 0) { + /* premature end of file */ + return -1; + } + else if (n != (size_t)-1) { + /* some bytes read, continue */ + done += n; + } + else if (errno != EAGAIN && errno != EINTR) { + /* real error */ + return -1; + } + } + return 0; +} + +void* +_elf_read(Elf *elf, void *buffer, size_t off, size_t len) { + void *tmp; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(off >= 0 && off + len <= elf->e_size); + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + } + else if (len) { + off += elf->e_base; + if (lseek(elf->e_fd, (off_t)off, SEEK_SET) != (off_t)off) { + seterr(ERROR_IO_SEEK); + } + else if (!(tmp = buffer) && !(tmp = malloc(len))) { + seterr(ERROR_IO_2BIG); + } + else if (xread(elf->e_fd, tmp, len)) { + seterr(ERROR_IO_READ); + if (tmp != buffer) { + free(tmp); + } + } + else { + return tmp; + } + } + return NULL; +} + +void* +_elf_mmap(Elf *elf) { +#if HAVE_MMAP + void *tmp; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_base == 0); + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + } + else if (elf->e_size) { + tmp = (void*)mmap(0, elf->e_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, elf->e_fd, 0); + if (tmp != (void*)-1) { + return tmp; + } + } +#endif /* HAVE_MMAP */ + return NULL; +} diff --git a/external/libelf/src/kind.c b/external/libelf/src/kind.c new file mode 100644 index 00000000..6f84f32e --- /dev/null +++ b/external/libelf/src/kind.c @@ -0,0 +1,33 @@ +/* +kind.c - implementation of the elf_kind(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: kind.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Kind +elf_kind(Elf *elf) { + if (!elf) { + return ELF_K_NONE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + return elf->e_kind; +} diff --git a/external/libelf/src/libelf.def b/external/libelf/src/libelf.def new file mode 100644 index 00000000..8085ffd1 --- /dev/null +++ b/external/libelf/src/libelf.def @@ -0,0 +1,82 @@ +LIBRARY libelf +VERSION 0.8 +EXPORTS + elf_begin + elf_cntl + elf_delscn + elf_end + elf_errmsg + elf_errno + elf_fill + elf_flagdata + elf_flagehdr + elf_flagelf + elf_flagphdr + elf_flagscn + elf_flagshdr + elf_getarhdr + elf_getarsym + elf_getbase + elf_getdata + elf_getident + elf_getscn + elf_hash + elf_kind + elf_memory + elf_ndxscn + elf_newdata + elf_newscn + elf_next + elf_nextscn + elf_rand + elf_rawdata + elf_rawfile + elf_strptr + elf_update + elf_version + elf32_checksum + elf32_fsize + elf32_getehdr + elf32_getphdr + elf32_getshdr + elf32_newehdr + elf32_newphdr + elf32_xlatetof + elf32_xlatetom + elf64_checksum + elf64_fsize + elf64_getehdr + elf64_getphdr + elf64_getshdr + elf64_newehdr + elf64_newphdr + elf64_xlatetof + elf64_xlatetom + elfx_movscn + elfx_remscn + gelf_checksum + gelf_fsize + gelf_getclass + gelf_getdyn + gelf_getehdr + gelf_getphdr + gelf_getrel + gelf_getrela + gelf_getshdr + gelf_getsym + gelf_msize + gelf_newehdr + gelf_newphdr + gelf_update_dyn + gelf_update_ehdr + gelf_update_phdr + gelf_update_rel + gelf_update_rela + gelf_update_shdr + gelf_update_sym + gelf_xlatetof + gelf_xlatetom + elf_getphnum + elf_getshnum + elf_getshstrndx + elfx_update_shstrndx diff --git a/external/libelf/src/memset.c b/external/libelf/src/memset.c new file mode 100644 index 00000000..e398bb55 --- /dev/null +++ b/external/libelf/src/memset.c @@ -0,0 +1,53 @@ +/* + * memset.c - replacement for memset(3), using duff's device. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#ifndef lint +static const char rcsid[] = "@(#) $Id: memset.c,v 1.11 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +#include /* for size_t */ +#include + +void* +_elf_memset(void *s, int c, size_t n) { + char *t = (char*)s; + + if (n) { + switch (n % 8u) { + do { + n -= 8; + default: + case 0: *t++ = (char)c; + case 7: *t++ = (char)c; + case 6: *t++ = (char)c; + case 5: *t++ = (char)c; + case 4: *t++ = (char)c; + case 3: *t++ = (char)c; + case 2: *t++ = (char)c; + case 1: *t++ = (char)c; + } + while (n > 8); + } + } + return s; +} diff --git a/external/libelf/src/ndxscn.c b/external/libelf/src/ndxscn.c new file mode 100644 index 00000000..c9ab9a89 --- /dev/null +++ b/external/libelf/src/ndxscn.c @@ -0,0 +1,33 @@ +/* +ndxscn.c - implementation of the elf_ndxscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: ndxscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +size_t +elf_ndxscn(Elf_Scn *scn) { + if (!scn) { + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + return scn->s_index; +} diff --git a/external/libelf/src/newdata.c b/external/libelf/src/newdata.c new file mode 100644 index 00000000..2a6eeba9 --- /dev/null +++ b/external/libelf/src/newdata.c @@ -0,0 +1,56 @@ +/* +newdata.c - implementation of the elf_newdata(3) function. +Copyright (C) 1995 - 2000 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: newdata.c,v 1.10 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Data* +elf_newdata(Elf_Scn *scn) { + Scn_Data *sd; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NULLSCN); + } + else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) { + seterr(ERROR_MEM_SCNDATA); + } + else { + *sd = _elf_data_init; + sd->sd_scn = scn; + sd->sd_data_flags = ELF_F_DIRTY; + sd->sd_freeme = 1; + sd->sd_data.d_version = _elf_version; + if (scn->s_data_n) { + scn->s_data_n->sd_link = sd; + } + else { + scn->s_data_1 = sd; + } + scn->s_data_n = sd; + return &sd->sd_data; + } + return NULL; +} diff --git a/external/libelf/src/newscn.c b/external/libelf/src/newscn.c new file mode 100644 index 00000000..69ba65de --- /dev/null +++ b/external/libelf/src/newscn.c @@ -0,0 +1,145 @@ +/* + * newscn.c - implementation of the elf_newscn(3) function. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: newscn.c,v 1.13 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +int +_elf_update_shnum(Elf *elf, size_t shnum) { + size_t extshnum = 0; + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_ehdr); + scn = elf->e_scn_1; + elf_assert(scn); + elf_assert(scn->s_index == 0); + if (shnum >= SHN_LORESERVE) { + extshnum = shnum; + shnum = 0; + } + if (elf->e_class == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = shnum; + scn->s_shdr32.sh_size = extshnum; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = shnum; + scn->s_shdr64.sh_size = extshnum; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return -1; + } + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_shdr_flags |= ELF_F_DIRTY; + return 0; +} + +static Elf_Scn* +_makescn(Elf *elf, size_t index) { + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(elf->e_ehdr); + elf_assert(_elf_scn_init.s_magic == SCN_MAGIC); + if (!(scn = (Elf_Scn*)malloc(sizeof(*scn)))) { + seterr(ERROR_MEM_SCN); + return NULL; + } + *scn = _elf_scn_init; + scn->s_elf = elf; + scn->s_scn_flags = ELF_F_DIRTY; + scn->s_shdr_flags = ELF_F_DIRTY; + scn->s_freeme = 1; + scn->s_index = index; + return scn; +} + +Elf_Scn* +_elf_first_scn(Elf *elf) { + Elf_Scn *scn; + + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if ((scn = elf->e_scn_1)) { + return scn; + } + if ((scn = _makescn(elf, 0))) { + elf->e_scn_1 = elf->e_scn_n = scn; + if (_elf_update_shnum(elf, 1)) { + free(scn); + elf->e_scn_1 = elf->e_scn_n = scn = NULL; + } + } + return scn; +} + +static Elf_Scn* +_buildscn(Elf *elf) { + Elf_Scn *scn; + + if (!_elf_first_scn(elf)) { + return NULL; + } + scn = elf->e_scn_n; + elf_assert(scn); + if (!(scn = _makescn(elf, scn->s_index + 1))) { + return NULL; + } + if (_elf_update_shnum(elf, scn->s_index + 1)) { + free(scn); + return NULL; + } + elf->e_scn_n = elf->e_scn_n->s_link = scn; + return scn; +} + +Elf_Scn* +elf_newscn(Elf *elf) { + Elf_Scn *scn; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable && !elf->e_ehdr) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (!elf->e_ehdr && !_elf_cook(elf)) { + return NULL; + } + else if ((scn = _buildscn(elf))) { + return scn; + } + return NULL; +} diff --git a/external/libelf/src/next.c b/external/libelf/src/next.c new file mode 100644 index 00000000..bf9a67b5 --- /dev/null +++ b/external/libelf/src/next.c @@ -0,0 +1,42 @@ +/* +next.c - implementation of the elf_next(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: next.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Cmd +elf_next(Elf *elf) { + if (!elf) { + return ELF_C_NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_parent) { + return ELF_C_NULL; + } + elf_assert(elf->e_parent->e_magic == ELF_MAGIC); + elf_assert(elf->e_parent->e_kind == ELF_K_AR); + elf->e_parent->e_off = elf->e_next; + if (elf->e_next == elf->e_parent->e_size) { + return ELF_C_NULL; + } + return ELF_C_READ; +} diff --git a/external/libelf/src/nextscn.c b/external/libelf/src/nextscn.c new file mode 100644 index 00000000..4543f83c --- /dev/null +++ b/external/libelf/src/nextscn.c @@ -0,0 +1,54 @@ +/* +nextscn.c - implementation of the elf_nextscn(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: nextscn.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Scn* +elf_nextscn(Elf *elf, Elf_Scn *scn) { + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (scn) { + elf_assert(scn->s_magic == SCN_MAGIC); + if (scn->s_elf == elf) { + return scn->s_link; + } + seterr(ERROR_ELFSCNMISMATCH); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_ehdr || _elf_cook(elf)) { + elf_assert(elf->e_ehdr); + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if (scn->s_index == 1) { + return scn; + } + } + seterr(ERROR_NOSUCHSCN); + } + return NULL; +} diff --git a/external/libelf/src/nlist.c b/external/libelf/src/nlist.c new file mode 100644 index 00000000..933d33fe --- /dev/null +++ b/external/libelf/src/nlist.c @@ -0,0 +1,253 @@ +/* + * nlist.c - implementation of the nlist(3) function. + * Copyright (C) 1995 - 2004 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: nlist.c,v 1.15 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +#if !defined(_WIN32) +#if HAVE_FCNTL_H +#include +#else +extern int open(); +#endif /* HAVE_FCNTL_H */ +#endif /* defined(_WIN32) */ + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif /* O_RDONLY */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +#define FILE_OPEN_MODE (O_RDONLY | O_BINARY) + +#define PRIME 217 + +struct hash { + const char* name; + unsigned long hash; + unsigned next; +}; + +static const char* +symbol_name(Elf *elf, const void *syms, const char *names, size_t nlimit, size_t index) { + size_t off; + + if (elf->e_class == ELFCLASS32) { + off = ((Elf32_Sym*)syms)[index].st_name; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + off = ((Elf64_Sym*)syms)[index].st_name; + } +#endif /* __LIBELF64 */ + else { + return NULL; + } + if (off >= 0 && off < nlimit) { + return &names[off]; + } + return NULL; +} + +static void +copy_symbol(Elf *elf, struct nlist *np, const void *syms, size_t index) { + if (elf->e_class == ELFCLASS32) { + np->n_value = ((Elf32_Sym*)syms)[index].st_value; + np->n_scnum = ((Elf32_Sym*)syms)[index].st_shndx; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + np->n_value = ((Elf64_Sym*)syms)[index].st_value; + np->n_scnum = ((Elf64_Sym*)syms)[index].st_shndx; + } +#endif /* __LIBELF64 */ + /* + * this needs more work + */ + np->n_type = 0; + np->n_sclass = 0; + np->n_numaux = 0; +} + +static int +_elf_nlist(Elf *elf, struct nlist *nl) { + unsigned first[PRIME]; + Elf_Scn *symtab = NULL; + Elf_Scn *strtab = NULL; + Elf_Data *symdata; + Elf_Data *strdata; + size_t symsize; + size_t nsymbols; + const char *name; + struct hash *table; + unsigned long hash; + unsigned i; + struct nlist *np; + + /* + * Get and translate ELF header, section table and so on. + * Must be class independent, so don't use elf32_get*(). + */ + if (elf->e_kind != ELF_K_ELF) { + return -1; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + + /* + * Find symbol table. If there is none, try dynamic symbols. + */ + for (symtab = elf->e_scn_1; symtab; symtab = symtab->s_link) { + if (symtab->s_type == SHT_SYMTAB) { + break; + } + if (symtab->s_type == SHT_DYNSYM) { + strtab = symtab; + } + } + if (!symtab && !(symtab = strtab)) { + return -1; + } + + /* + * Get associated string table. + */ + i = 0; + if (elf->e_class == ELFCLASS32) { + i = symtab->s_shdr32.sh_link; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + i = symtab->s_shdr64.sh_link; + } +#endif /* __LIBELF64 */ + if (i == 0) { + return -1; + } + for (strtab = elf->e_scn_1; strtab; strtab = strtab->s_link) { + if (strtab->s_index == i) { + break; + } + } + if (!strtab || strtab->s_type != SHT_STRTAB) { + return -1; + } + + /* + * Get and translate section data. + */ + symdata = elf_getdata(symtab, NULL); + strdata = elf_getdata(strtab, NULL); + if (!symdata || !strdata) { + return -1; + } + symsize = _msize(elf->e_class, _elf_version, ELF_T_SYM); + elf_assert(symsize); + nsymbols = symdata->d_size / symsize; + if (!symdata->d_buf || !strdata->d_buf || !nsymbols || !strdata->d_size) { + return -1; + } + + /* + * Build a simple hash table. + */ + if (!(table = (struct hash*)malloc(nsymbols * sizeof(*table)))) { + return -1; + } + for (i = 0; i < PRIME; i++) { + first[i] = 0; + } + for (i = 0; i < nsymbols; i++) { + table[i].name = NULL; + table[i].hash = 0; + table[i].next = 0; + } + for (i = 1; i < nsymbols; i++) { + name = symbol_name(elf, symdata->d_buf, strdata->d_buf, + strdata->d_size, i); + if (name == NULL) { + free(table); + return -1; + } + if (*name != '\0') { + table[i].name = name; + table[i].hash = elf_hash((unsigned char*)name); + hash = table[i].hash % PRIME; + table[i].next = first[hash]; + first[hash] = i; + } + } + + /* + * Lookup symbols, one by one. + */ + for (np = nl; (name = np->n_name) && *name; np++) { + hash = elf_hash((unsigned char*)name); + for (i = first[hash % PRIME]; i; i = table[i].next) { + if (table[i].hash == hash && !strcmp(table[i].name, name)) { + break; + } + } + if (i) { + copy_symbol(elf, np, symdata->d_buf, i); + } + else { + np->n_value = 0; + np->n_scnum = 0; + np->n_type = 0; + np->n_sclass = 0; + np->n_numaux = 0; + } + } + free(table); + return 0; +} + +int +nlist(const char *filename, struct nlist *nl) { + int result = -1; + unsigned oldver; + Elf *elf; + int fd; + + if ((oldver = elf_version(EV_CURRENT)) != EV_NONE) { + if ((fd = open(filename, FILE_OPEN_MODE)) != -1) { + if ((elf = elf_begin(fd, ELF_C_READ, NULL))) { + result = _elf_nlist(elf, nl); + elf_end(elf); + } + close(fd); + } + elf_version(oldver); + } + if (result) { + while (nl->n_name && *nl->n_name) { + nl->n_value = 0; + nl++; + } + } + return result; +} diff --git a/external/libelf/src/nlist.h b/external/libelf/src/nlist.h new file mode 100644 index 00000000..27a452ec --- /dev/null +++ b/external/libelf/src/nlist.h @@ -0,0 +1,48 @@ +/* + * nlist.h - public header file for nlist(3). + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: nlist.h,v 1.10 2008/05/23 08:15:35 michael Exp $ */ + +#ifndef _NLIST_H +#define _NLIST_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct nlist { + char* n_name; + long n_value; + short n_scnum; + unsigned short n_type; + char n_sclass; + char n_numaux; +}; + +#if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32) +extern int nlist(const char *__filename, struct nlist *__nl); +#else /* __STDC__ || defined(__cplusplus) */ +extern int nlist(); +#endif /* __STDC__ || defined(__cplusplus) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NLIST_H */ diff --git a/external/libelf/src/opt.delscn.c b/external/libelf/src/opt.delscn.c new file mode 100644 index 00000000..2201155a --- /dev/null +++ b/external/libelf/src/opt.delscn.c @@ -0,0 +1,205 @@ +/* +opt.delscn.c - implementation of the elf_delscn(3) function. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: opt.delscn.c,v 1.12 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +static size_t +_newindex(size_t old, size_t index) { + return old == index ? SHN_UNDEF : (old > index ? old - 1 : old); +} + +static void +_elf32_update_shdr(Elf *elf, size_t index) { + Elf32_Shdr *shdr; + Elf_Scn *scn; + + ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + shdr = &scn->s_shdr32; + switch (shdr->sh_type) { + case SHT_REL: + case SHT_RELA: + shdr->sh_info = _newindex(shdr->sh_info, index); + /* fall through */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + case SHT_HASH: + case SHT_SYMTAB: +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: + case SHT_SUNW_verneed: + case SHT_SUNW_versym: +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: + case SHT_GNU_verneed: + case SHT_GNU_versym: +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + shdr->sh_link = _newindex(shdr->sh_link, index); + /* fall through */ + default: + break; + } + } +} + +#if __LIBELF64 + +static void +_elf64_update_shdr(Elf *elf, size_t index) { + Elf64_Shdr *shdr; + Elf_Scn *scn; + + ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + shdr = &scn->s_shdr64; + switch (shdr->sh_type) { + case SHT_REL: + case SHT_RELA: + shdr->sh_info = _newindex(shdr->sh_info, index); + /* fall through */ + case SHT_DYNSYM: + case SHT_DYNAMIC: + case SHT_HASH: + case SHT_SYMTAB: +#if __LIBELF_SYMBOL_VERSIONS +#if __LIBELF_SUN_SYMBOL_VERSIONS + case SHT_SUNW_verdef: + case SHT_SUNW_verneed: + case SHT_SUNW_versym: +#else /* __LIBELF_SUN_SYMBOL_VERSIONS */ + case SHT_GNU_verdef: + case SHT_GNU_verneed: + case SHT_GNU_versym: +#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */ +#endif /* __LIBELF_SYMBOL_VERSIONS */ + shdr->sh_link = _newindex(shdr->sh_link, index); + /* fall through */ + default: + break; + } + } +} + +#endif /* __LIBELF64 */ + +size_t +elf_delscn(Elf *elf, Elf_Scn *scn) { + Elf_Scn *pscn; + Scn_Data *sd; + Scn_Data *tmp; + size_t index; + + if (!elf || !scn) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(elf->e_ehdr); + if (scn->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + + /* + * Find previous section. + */ + for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) { + if (pscn->s_link == scn) { + break; + } + } + if (pscn->s_link != scn) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + /* + * Unlink section. + */ + if (elf->e_scn_n == scn) { + elf->e_scn_n = pscn; + } + pscn->s_link = scn->s_link; + index = scn->s_index; + /* + * Free section descriptor and data. + */ + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + elf_assert(scn->s_index > 0); + free(scn); + } + /* + * Adjust section indices. + */ + for (scn = pscn->s_link; scn; scn = scn->s_link) { + elf_assert(scn->s_index > index); + scn->s_index--; + } + /* + * Adjust ELF header and well-known section headers. + */ + if (elf->e_class == ELFCLASS32) { + _elf32_update_shdr(elf, index); + return index; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + _elf64_update_shdr(elf, index); + return index; + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return SHN_UNDEF; +} diff --git a/external/libelf/src/private.h b/external/libelf/src/private.h new file mode 100644 index 00000000..2b772dca --- /dev/null +++ b/external/libelf/src/private.h @@ -0,0 +1,446 @@ +/* + * private.h - private definitions for libelf. + * Copyright (C) 1995 - 2007 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* @(#) $Id: private.h,v 1.40 2009/11/01 13:04:19 michael Exp $ */ + +#ifndef _PRIVATE_H +#define _PRIVATE_H + +#define __LIBELF_INTERNAL__ 1 + +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +/* + * Workaround for GLIBC bug: + * include before + */ +#if HAVE_STDINT_H +#include +#endif +#include + +#if STDC_HEADERS +# include +# include +#else /* STDC_HEADERS */ +extern void *malloc(), *realloc(); +extern void free(), bcopy(), abort(); +extern int strcmp(), strncmp(), memcmp(); +extern void *memcpy(), *memmove(), *memset(); +#endif /* STDC_HEADERS */ + +#if defined(_WIN32) +#include +#else +#if HAVE_UNISTD_H +# include +#else /* HAVE_UNISTD_H */ +extern int read(), write(), close(); +extern off_t lseek(); +#if HAVE_FTRUNCATE +extern int ftruncate(); +#endif /* HAVE_FTRUNCATE */ +#endif /* HAVE_UNISTD_H */ +#endif /* defined(_WIN32) */ + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif /* SEEK_SET */ +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif /* SEEK_CUR */ +#ifndef SEEK_END +#define SEEK_END 2 +#endif /* SEEK_END */ + +#if !HAVE_MEMCMP +# define memcmp strncmp +#endif /* !HAVE_MEMCMP */ +#if !HAVE_MEMCPY +# define memcpy(d,s,n) bcopy(s,d,n) +#endif /* !HAVE_MEMCPY */ +#if !HAVE_MEMMOVE +# define memmove(d,s,n) bcopy(s,d,n) +#endif /* !HAVE_MEMMOVE */ + +#if !HAVE_MEMSET +# define memset _elf_memset +extern void *_elf_memset(); +#endif /* !HAVE_MEMSET */ + +#if HAVE_STRUCT_NLIST_DECLARATION +# define nlist __override_nlist_declaration +#endif /* HAVE_STRUCT_NLIST_DECLARATION */ + +#if __LIBELF_NEED_LINK_H +# include +#elif __LIBELF_NEED_SYS_LINK_H +# include +#endif /* __LIBELF_NEED_LINK_H */ + +#if HAVE_AR_H +#include +#else /* HAVE_AR_H */ + +#define ARMAG "!\n" +#define SARMAG 8 + +struct ar_hdr { + char ar_name[16]; + char ar_date[12]; + char ar_uid[6]; + char ar_gid[6]; + char ar_mode[8]; + char ar_size[10]; + char ar_fmag[2]; +}; + +#define ARFMAG "`\n" + +#endif /* HAVE_AR_H */ + +#include + +#if HAVE_STRUCT_NLIST_DECLARATION +# undef nlist +#endif /* HAVE_STRUCT_NLIST_DECLARATION */ + +#if __LIBELF64 +#include +#endif /* __LIBELF64 */ + +typedef struct Scn_Data Scn_Data; + +/* + * ELF descriptor + */ +struct Elf { + /* common */ + size_t e_size; /* file/member size */ + size_t e_dsize; /* size of memory image */ + Elf_Kind e_kind; /* kind of file */ + char* e_data; /* file/member data */ + char* e_rawdata; /* file/member raw data */ + size_t e_idlen; /* identifier size */ + int e_fd; /* file descriptor */ + unsigned e_count; /* activation count */ + /* archive members (still common) */ + Elf* e_parent; /* NULL if not an archive member */ + size_t e_next; /* 0 if not an archive member */ + size_t e_base; /* 0 if not an archive member */ + Elf* e_link; /* next archive member or NULL */ + Elf_Arhdr* e_arhdr; /* archive member header or NULL */ + /* archives */ + size_t e_off; /* current member offset (for elf_begin) */ + Elf* e_members; /* linked list of active archive members */ + char* e_symtab; /* archive symbol table */ + size_t e_symlen; /* length of archive symbol table */ + char* e_strtab; /* archive string table */ + size_t e_strlen; /* length of archive string table */ + /* ELF files */ + unsigned e_class; /* ELF class */ + unsigned e_encoding; /* ELF data encoding */ + unsigned e_version; /* ELF version */ + char* e_ehdr; /* ELF header */ + char* e_phdr; /* ELF program header table */ + size_t e_phnum; /* size of program header table */ + Elf_Scn* e_scn_1; /* first section */ + Elf_Scn* e_scn_n; /* last section */ + unsigned e_elf_flags; /* elf flags (ELF_F_*) */ + unsigned e_ehdr_flags; /* ehdr flags (ELF_F_*) */ + unsigned e_phdr_flags; /* phdr flags (ELF_F_*) */ + /* misc flags */ + unsigned e_readable : 1; /* file is readable */ + unsigned e_writable : 1; /* file is writable */ + unsigned e_disabled : 1; /* e_fd has been disabled */ + unsigned e_cooked : 1; /* e_data was modified */ + unsigned e_free_syms : 1; /* e_symtab is malloc'ed */ + unsigned e_unmap_data : 1; /* e_data is mmap'ed */ + unsigned e_memory : 1; /* created by elf_memory() */ + /* magic number for debugging */ + long e_magic; +}; + +#define ELF_MAGIC 0x012b649e + +#define INIT_ELF {\ + /* e_size */ 0,\ + /* e_dsize */ 0,\ + /* e_kind */ ELF_K_NONE,\ + /* e_data */ NULL,\ + /* e_rawdata */ NULL,\ + /* e_idlen */ 0,\ + /* e_fd */ -1,\ + /* e_count */ 1,\ + /* e_parent */ NULL,\ + /* e_next */ 0,\ + /* e_base */ 0,\ + /* e_link */ NULL,\ + /* e_arhdr */ NULL,\ + /* e_off */ 0,\ + /* e_members */ NULL,\ + /* e_symtab */ NULL,\ + /* e_symlen */ 0,\ + /* e_strtab */ NULL,\ + /* e_strlen */ 0,\ + /* e_class */ ELFCLASSNONE,\ + /* e_encoding */ ELFDATANONE,\ + /* e_version */ EV_NONE,\ + /* e_ehdr */ NULL,\ + /* e_phdr */ NULL,\ + /* e_phnum */ 0,\ + /* e_scn_1 */ NULL,\ + /* e_scn_n */ NULL,\ + /* e_elf_flags */ 0,\ + /* e_ehdr_flags */ 0,\ + /* e_phdr_flags */ 0,\ + /* e_readable */ 0,\ + /* e_writable */ 0,\ + /* e_disabled */ 0,\ + /* e_cooked */ 0,\ + /* e_free_syms */ 0,\ + /* e_unmap_data */ 0,\ + /* e_memory */ 0,\ + /* e_magic */ ELF_MAGIC\ +} + +/* + * Section descriptor + */ +struct Elf_Scn { + Elf_Scn* s_link; /* pointer to next Elf_Scn */ + Elf* s_elf; /* pointer to elf descriptor */ + size_t s_index; /* number of this section */ + unsigned s_scn_flags; /* section flags (ELF_F_*) */ + unsigned s_shdr_flags; /* shdr flags (ELF_F_*) */ + Scn_Data* s_data_1; /* first data buffer */ + Scn_Data* s_data_n; /* last data buffer */ + Scn_Data* s_rawdata; /* raw data buffer */ + /* data copied from shdr */ + unsigned s_type; /* section type */ + size_t s_offset; /* section offset */ + size_t s_size; /* section size */ + /* misc flags */ + unsigned s_freeme : 1; /* this Elf_Scn was malloc'ed */ + /* section header */ + union { +#if __LIBELF64 + Elf64_Shdr u_shdr64; +#endif /* __LIBELF64 */ + Elf32_Shdr u_shdr32; + } s_uhdr; + /* magic number for debugging */ + long s_magic; +}; +#define s_shdr32 s_uhdr.u_shdr32 +#define s_shdr64 s_uhdr.u_shdr64 + +#define SCN_MAGIC 0x012c747d + +#define INIT_SCN {\ + /* s_link */ NULL,\ + /* s_elf */ NULL,\ + /* s_index */ 0,\ + /* s_scn_flags */ 0,\ + /* s_shdr_flags */ 0,\ + /* s_data_1 */ NULL,\ + /* s_data_n */ NULL,\ + /* s_rawdata */ NULL,\ + /* s_type */ SHT_NULL,\ + /* s_offset */ 0,\ + /* s_size */ 0,\ + /* s_freeme */ 0,\ + /* s_uhdr */ {{0,}},\ + /* s_magic */ SCN_MAGIC\ +} + +/* + * Data descriptor + */ +struct Scn_Data { + Elf_Data sd_data; /* must be first! */ + Scn_Data* sd_link; /* pointer to next Scn_Data */ + Elf_Scn* sd_scn; /* pointer to section */ + char* sd_memdata; /* memory image of section */ + unsigned sd_data_flags; /* data flags (ELF_F_*) */ + /* misc flags */ + unsigned sd_freeme : 1; /* this Scn_Data was malloc'ed */ + unsigned sd_free_data : 1; /* sd_memdata is malloc'ed */ + /* magic number for debugging */ + long sd_magic; +}; + +#define DATA_MAGIC 0x01072639 + +#define INIT_DATA {\ + {\ + /* d_buf */ NULL,\ + /* d_type */ ELF_T_BYTE,\ + /* d_size */ 0,\ + /* d_off */ 0,\ + /* d_align */ 0,\ + /* d_version */ EV_NONE\ + },\ + /* sd_link */ NULL,\ + /* sd_scn */ NULL,\ + /* sd_memdata */ NULL,\ + /* sd_data_flags */ 0,\ + /* sd_freeme */ 0,\ + /* sd_free_data */ 0,\ + /* sd_magic */ DATA_MAGIC\ +} + +/* + * Private status variables + */ +extern unsigned _elf_version; +extern int _elf_errno; +extern int _elf_fill; +extern int _elf_sanity_checks; +#define SANITY_CHECK_STRPTR (1u << 0) + +/* + * Private functions + */ +extern void *_elf_read __P((Elf*, void*, size_t, size_t)); +extern void *_elf_mmap __P((Elf*)); +extern int _elf_cook __P((Elf*)); +extern char *_elf_getehdr __P((Elf*, unsigned)); +extern char *_elf_getphdr __P((Elf*, unsigned)); +extern Elf_Data *_elf_xlatetom __P((const Elf*, Elf_Data*, const Elf_Data*)); +extern Elf_Type _elf_scn_type __P((unsigned)); +extern size_t _elf32_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof)); +extern size_t _elf64_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof)); +extern int _elf_update_shnum(Elf *__elf, size_t __shnum); +extern Elf_Scn *_elf_first_scn(Elf *__elf); + +/* + * Special translators + */ +extern size_t _elf_verdef_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verdef_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n)); +extern size_t _elf_verneed_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n)); + +/* + * Private data + */ +extern const Elf_Scn _elf_scn_init; +extern const Scn_Data _elf_data_init; +extern const size_t _elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2]; + +/* + * Access macros for _elf_fmsize[] + */ +#define _fmsize(c,v,t,w) \ + (_elf_fmsize[(c)-ELFCLASS32][(v)-EV_NONE-1][(t)-ELF_T_BYTE][(w)]) +#define _fsize(c,v,t) _fmsize((c),(v),(t),1) +#define _msize(c,v,t) _fmsize((c),(v),(t),0) + +/* + * Various checks + */ +#define valid_class(c) ((c) >= ELFCLASS32 && (c) <= ELFCLASS64) +#define valid_encoding(e) ((e) >= ELFDATA2LSB && (e) <= ELFDATA2MSB) +#define valid_version(v) ((v) > EV_NONE && (v) <= EV_CURRENT) +#define valid_type(t) ((unsigned)(t) < ELF_T_NUM) + +/* + * Error codes + */ +enum { +#define __err__(a,b) a, +#include /* include constants from errors.h */ +#undef __err__ +ERROR_NUM +}; + +#define seterr(err) (_elf_errno = (err)) + +/* + * Sizes of data types (external representation) + * These definitions should be in , but... + */ +#ifndef ELF32_FSZ_ADDR +# define ELF32_FSZ_ADDR 4 +# define ELF32_FSZ_HALF 2 +# define ELF32_FSZ_OFF 4 +# define ELF32_FSZ_SWORD 4 +# define ELF32_FSZ_WORD 4 +#endif /* ELF32_FSZ_ADDR */ +#ifndef ELF64_FSZ_ADDR +# define ELF64_FSZ_ADDR 8 +# define ELF64_FSZ_HALF 2 +# define ELF64_FSZ_OFF 8 +# define ELF64_FSZ_SWORD 4 +# define ELF64_FSZ_SXWORD 8 +# define ELF64_FSZ_WORD 4 +# define ELF64_FSZ_XWORD 8 +#endif /* ELF64_FSZ_ADDR */ + +/* + * More missing pieces, in no particular order + */ +#ifndef SHT_SYMTAB_SHNDX +#define SHT_SYMTAB_SHNDX 18 +#endif /* SHT_SYMTAB_SHNDX */ + +#ifndef SHN_XINDEX +#define SHN_XINDEX 0xffff +#endif /* SHN_XINDEX */ + +#ifndef PN_XNUM +#define PN_XNUM 0xffff +#endif /* PN_XNUM */ + +/* + * Debugging + */ +#if ENABLE_DEBUG +extern void __elf_assert __P((const char*, unsigned, const char*)); +# if (__STDC__ + 0) +# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,#x);}while(0) +# else /* __STDC__ */ +# define elf_assert(x) do{if(!(x))__elf_assert(__FILE__,__LINE__,"x");}while(0) +# endif /* __STDC__ */ +#else /* ENABLE_DEBUG */ +# define elf_assert(x) do{}while(0) +#endif /* ENABLE_DEBUG */ + +/* + * Return values for certain functions + */ +#define LIBELF_SUCCESS 1 +#define LIBELF_FAILURE 0 + +#endif /* _PRIVATE_H */ diff --git a/external/libelf/src/rand.c b/external/libelf/src/rand.c new file mode 100644 index 00000000..9cad1266 --- /dev/null +++ b/external/libelf/src/rand.c @@ -0,0 +1,43 @@ +/* +rand.c - implementation of the elf_rand(3) function. +Copyright (C) 1995 - 1998 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rand.c,v 1.7 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +size_t +elf_rand(Elf *elf, size_t offset) { + if (!elf) { + return 0; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_AR) { + seterr(ERROR_NOTARCHIVE); + } + else if (offset <= 0 || offset > elf->e_size) { + seterr(ERROR_BADOFF); + } + else { + elf->e_off = offset; + return offset; + } + return 0; +} diff --git a/external/libelf/src/rawdata.c b/external/libelf/src/rawdata.c new file mode 100644 index 00000000..5d9a9f30 --- /dev/null +++ b/external/libelf/src/rawdata.c @@ -0,0 +1,89 @@ +/* +rawdata.c - implementation of the elf_rawdata(3) function. +Copyright (C) 1995 - 2000 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rawdata.c,v 1.10 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +Elf_Data* +elf_rawdata(Elf_Scn *scn, Elf_Data *data) { + Scn_Data *sd; + Elf *elf; + + if (!scn) { + return NULL; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf = scn->s_elf; + elf_assert(elf); + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable) { + return NULL; + } + else if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) { + seterr(ERROR_NULLSCN); + } + else if (data) { + return NULL; + } + else if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + return &sd->sd_data; + } + else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) { + seterr(ERROR_OUTSIDE); + } + else if (scn->s_type != SHT_NOBITS + && scn->s_offset + scn->s_size > elf->e_size) { + seterr(ERROR_TRUNC_SCN); + } + else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) { + seterr(ERROR_MEM_SCNDATA); + } + else { + *sd = _elf_data_init; + sd->sd_scn = scn; + sd->sd_freeme = 1; + sd->sd_data.d_size = scn->s_size; + sd->sd_data.d_version = _elf_version; + if (scn->s_type != SHT_NOBITS && scn->s_size) { + if (!(sd->sd_memdata = (char*)malloc(scn->s_size))) { + seterr(ERROR_IO_2BIG); + free(sd); + return NULL; + } + else if (elf->e_rawdata) { + memcpy(sd->sd_memdata, elf->e_rawdata + scn->s_offset, scn->s_size); + } + else if (!_elf_read(elf, sd->sd_memdata, scn->s_offset, scn->s_size)) { + free(sd->sd_memdata); + free(sd); + return NULL; + } + sd->sd_data.d_buf = sd->sd_memdata; + sd->sd_free_data = 1; + } + scn->s_rawdata = sd; + return &sd->sd_data; + } + return NULL; +} diff --git a/external/libelf/src/rawfile.c b/external/libelf/src/rawfile.c new file mode 100644 index 00000000..43335c4f --- /dev/null +++ b/external/libelf/src/rawfile.c @@ -0,0 +1,54 @@ +/* + * rawfile.c - implementation of the elf_rawfile(3) function. + * Copyright (C) 1995 - 2009 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: rawfile.c,v 1.8 2009/05/22 17:07:46 michael Exp $"; +#endif /* lint */ + +char* +elf_rawfile(Elf *elf, size_t *ptr) { + size_t tmp; + + if (!ptr) { + ptr = &tmp; + } + *ptr = 0; + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!elf->e_readable) { + return NULL; + } + else if (elf->e_size) { + if (!elf->e_rawdata) { + elf_assert(elf->e_data); + if (!elf->e_cooked) { + elf->e_rawdata = elf->e_data; + } + else if (!(elf->e_rawdata = _elf_read(elf, NULL, 0, elf->e_size))) { + return NULL; + } + } + *ptr = elf->e_size; + } + return elf->e_rawdata; +} diff --git a/external/libelf/src/strptr.c b/external/libelf/src/strptr.c new file mode 100644 index 00000000..30e217ec --- /dev/null +++ b/external/libelf/src/strptr.c @@ -0,0 +1,150 @@ +/* + * strptr.c - implementation of the elf_strptr(3) function. + * Copyright (C) 1995 - 2007 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: strptr.c,v 1.12 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +char* +elf_strptr(Elf *elf, size_t section, size_t offset) { + Elf_Data *data; + Elf_Scn *scn; + size_t n; + char *s; + + if (!elf) { + return NULL; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (!(scn = elf_getscn(elf, section))) { + return NULL; + } + if (scn->s_index == SHN_UNDEF) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + /* + * checking the section header is more appropriate + */ + if (elf->e_class == ELFCLASS32) { + if (scn->s_shdr32.sh_type != SHT_STRTAB) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + if (scn->s_shdr64.sh_type != SHT_STRTAB) { + seterr(ERROR_NOSTRTAB); + return NULL; + } + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + return NULL; + } + else { + seterr(ERROR_UNKNOWN_CLASS); + return NULL; + } + /* + * Find matching buffer + */ + n = 0; + data = NULL; + if (elf->e_elf_flags & ELF_F_LAYOUT) { + /* + * Programmer is responsible for d_off + * Note: buffers may be in any order! + */ + while ((data = elf_getdata(scn, data))) { + n = data->d_off; + if (offset >= n && offset - n < data->d_size) { + /* + * Found it + */ + break; + } + } + } + else { + /* + * Calculate offsets myself + */ + while ((data = elf_getdata(scn, data))) { + if (data->d_align > 1) { + n += data->d_align - 1; + n -= n % data->d_align; + } + if (offset < n) { + /* + * Invalid offset: points into a hole + */ + seterr(ERROR_BADSTROFF); + return NULL; + } + if (offset - n < data->d_size) { + /* + * Found it + */ + break; + } + n += data->d_size; + } + } + if (data == NULL) { + /* + * Not found + */ + seterr(ERROR_BADSTROFF); + return NULL; + } + if (data->d_buf == NULL) { + /* + * Buffer is NULL (usually the programmers' fault) + */ + seterr(ERROR_NULLBUF); + return NULL; + } + offset -= n; + s = (char*)data->d_buf; + if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) { + return s + offset; + } + /* + * Perform extra sanity check + */ + for (n = offset; n < data->d_size; n++) { + if (s[n] == '\0') { + /* + * Return properly NUL terminated string + */ + return s + offset; + } + } + /* + * String is not NUL terminated + * Return error to avoid SEGV in application + */ + seterr(ERROR_UNTERM); + return NULL; +} diff --git a/external/libelf/src/swap64.c b/external/libelf/src/swap64.c new file mode 100644 index 00000000..397bd5b4 --- /dev/null +++ b/external/libelf/src/swap64.c @@ -0,0 +1,81 @@ +/* +swap64.c - 64-bit byte swapping functions. +Copyright (C) 1995 - 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: swap64.c,v 1.6 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +__libelf_u64_t +_elf_load_u64L(const unsigned char *from) { + return ((__libelf_u64_t)__load_u32L(from + 4) << 32) + | (__libelf_u64_t)__load_u32L(from); +} + +__libelf_u64_t +_elf_load_u64M(const unsigned char *from) { + return ((__libelf_u64_t)__load_u32M(from) << 32) + | (__libelf_u64_t)__load_u32M(from + 4); +} + +__libelf_i64_t +_elf_load_i64L(const unsigned char *from) { + return ((__libelf_i64_t)__load_i32L(from + 4) << 32) + | (__libelf_u64_t)__load_u32L(from); +} + +__libelf_i64_t +_elf_load_i64M(const unsigned char *from) { + return ((__libelf_i64_t)__load_i32M(from) << 32) + | (__libelf_u64_t)__load_u32M(from + 4); +} + +void +_elf_store_u64L(unsigned char *to, __libelf_u64_t v) { + __store_u32L(to, (__libelf_u32_t)v); + v >>= 32; + __store_u32L(to + 4, (__libelf_u32_t)v); +} + +void +_elf_store_u64M(unsigned char *to, __libelf_u64_t v) { + __store_u32M(to + 4, (__libelf_u32_t)v); + v >>= 32; + __store_u32M(to, (__libelf_u32_t)v); +} + +void +_elf_store_i64L(unsigned char *to, __libelf_u64_t v) { + __store_u32L(to, (__libelf_u32_t)v); + v >>= 32; + __store_i32L(to + 4, (__libelf_u32_t)v); +} + +void +_elf_store_i64M(unsigned char *to, __libelf_u64_t v) { + __store_u32M(to + 4, (__libelf_u32_t)v); + v >>= 32; + __store_i32M(to, (__libelf_u32_t)v); +} + +#endif /* __LIBELF64 */ diff --git a/external/libelf/src/update.c b/external/libelf/src/update.c new file mode 100644 index 00000000..085ddea5 --- /dev/null +++ b/external/libelf/src/update.c @@ -0,0 +1,1021 @@ +/* + * update.c - implementation of the elf_update(3) function. + * Copyright (C) 1995 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: update.c,v 1.34 2009/05/22 17:08:09 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#endif /* HAVE_MMAP */ + +static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8); +#define native_encoding (*(unsigned char*)&__encoding) + +#define rewrite(var,val,f) \ + do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0) + +#define align(var,val) \ + do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0) + +#undef max +#define max(a,b) ((a)>(b)?(a):(b)) + +static off_t +scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) { + Elf *elf = scn->s_elf; + Elf_Data *data; + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + size_t scn_align = 1; + size_t len = 0; + Scn_Data *sd; + size_t fsize; + + if (!(sd = scn->s_data_1)) { + /* no data in section */ + *algn = scn_align; + return (off_t)len; + } + /* load data from file, if any */ + if (!(data = elf_getdata(scn, NULL))) { + return (off_t)-1; + } + elf_assert(data == &sd->sd_data); + for (; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + + if (!valid_version(sd->sd_data.d_version)) { + return (off_t)-1; + } + + fsize = sd->sd_data.d_size; + if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) { + if (elf->e_class == ELFCLASS32) { + fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1); + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1); + } +#endif /* __LIBELF64 */ + else { + elf_assert(valid_class(elf->e_class)); + seterr(ERROR_UNIMPLEMENTED); + return (off_t)-1; + } + if (fsize == (size_t)-1) { + return (off_t)-1; + } + } + + if (layout) { + align(len, sd->sd_data.d_align); + scn_align = max(scn_align, sd->sd_data.d_align); + rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags); + len += fsize; + } + else { + len = max(len, sd->sd_data.d_off + fsize); + } + + *flag |= sd->sd_data_flags; + } + *algn = scn_align; + return (off_t)len; +} + +static size_t +scn_entsize(const Elf *elf, unsigned version, unsigned stype) { + Elf_Type type; + + switch ((type = _elf_scn_type(stype))) { + case ELF_T_BYTE: + return 0; + case ELF_T_VDEF: + case ELF_T_VNEED: + return 0; /* What else can I do? Thank you, Sun! */ + default: + return _fsize(elf->e_class, version, type); + } +} + +static off_t +_elf32_layout(Elf *elf, unsigned *flag) { + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0; + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr; + size_t off = 0; + unsigned version; + unsigned encoding; + size_t align_addr; + size_t entsize; + unsigned phnum; + unsigned shnum; + Elf_Scn *scn; + + *flag = elf->e_elf_flags | elf->e_phdr_flags; + + if ((version = ehdr->e_version) == EV_NONE) { + version = EV_CURRENT; + } + if (!valid_version(version)) { + seterr(ERROR_UNKNOWN_VERSION); + return -1; + } + if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) { + encoding = native_encoding; + } + if (!valid_encoding(encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + return -1; + } + entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR); + elf_assert(entsize); + rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags); + off = entsize; + + align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR); + elf_assert(align_addr); + + if ((phnum = elf->e_phnum)) { + entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags); + off += phnum * entsize; + } + else { + off = max(off, ehdr->e_phoff + phnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags); + } + } + if (phnum >= PN_XNUM) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + elf_assert(scn); + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_info, phnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + phnum = PN_XNUM; + } + rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags); + rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags); + + for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) { + Elf32_Shdr *shdr = &scn->s_shdr32; + size_t scn_align = 1; + off_t len; + + elf_assert(scn->s_index == shnum); + + *flag |= scn->s_scn_flags; + + if (scn->s_index == SHN_UNDEF) { + rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags); + if (layout) { + rewrite(shdr->sh_offset, 0, scn->s_shdr_flags); + rewrite(shdr->sh_size, 0, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags); + } + *flag |= scn->s_shdr_flags; + continue; + } + if (shdr->sh_type == SHT_NULL) { + *flag |= scn->s_shdr_flags; + continue; + } + + len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag); + if (len == -1) { + return -1; + } + + /* + * Never override the program's choice. + */ + if (shdr->sh_entsize == 0) { + entsize = scn_entsize(elf, version, shdr->sh_type); + if (entsize > 1) { + rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); + } + } + + if (layout) { + align(off, scn_align); + rewrite(shdr->sh_offset, off, scn->s_shdr_flags); + rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags); + + if (shdr->sh_type != SHT_NOBITS) { + off += (size_t)len; + } + } + else if ((size_t)len > shdr->sh_size) { + seterr(ERROR_SCN2SMALL); + return -1; + } + else { + Elf_Scn *scn2; + size_t end1, end2; + + end1 = shdr->sh_offset; + if (shdr->sh_type != SHT_NOBITS) { + end1 += shdr->sh_size; + } + if (!allow_overlap && shdr->sh_offset < off) { + /* + * check for overlapping sections + */ + for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) { + if (scn2 == scn) { + break; + } + end2 = scn2->s_shdr32.sh_offset; + if (scn2->s_shdr32.sh_type != SHT_NOBITS) { + end2 += scn2->s_shdr32.sh_size; + } + if (end1 > scn2->s_shdr32.sh_offset + && end2 > shdr->sh_offset) { + seterr(ERROR_SCN_OVERLAP); + return -1; + } + } + } + if (off < end1) { + off = end1; + } + } + *flag |= scn->s_shdr_flags; + } + + if (shnum) { + entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags); + off += shnum * entsize; + } + else { + off = max(off, ehdr->e_shoff + shnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags); + } + } + if (shnum >= SHN_LORESERVE) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_size, shnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + shnum = 0; + } + rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags); + rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags); + + rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags); + rewrite(ehdr->e_version, version, elf->e_ehdr_flags); + + *flag |= elf->e_ehdr_flags; + + return off; +} + +#if __LIBELF64 + +static off_t +_elf64_layout(Elf *elf, unsigned *flag) { + int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0; + int allow_overlap = (elf->e_elf_flags & ELF_F_LAYOUT_OVERLAP) != 0; + Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr; + size_t off = 0; + unsigned version; + unsigned encoding; + size_t align_addr; + size_t entsize; + unsigned phnum; + unsigned shnum; + Elf_Scn *scn; + + *flag = elf->e_elf_flags | elf->e_phdr_flags; + + if ((version = ehdr->e_version) == EV_NONE) { + version = EV_CURRENT; + } + if (!valid_version(version)) { + seterr(ERROR_UNKNOWN_VERSION); + return -1; + } + if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) { + encoding = native_encoding; + } + if (!valid_encoding(encoding)) { + seterr(ERROR_UNKNOWN_ENCODING); + return -1; + } + entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR); + elf_assert(entsize); + rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags); + off = entsize; + + align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR); + elf_assert(align_addr); + + if ((phnum = elf->e_phnum)) { + entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags); + off += phnum * entsize; + } + else { + off = max(off, ehdr->e_phoff + phnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags); + } + } + if (phnum >= PN_XNUM) { + Elf_Scn *scn = elf->e_scn_1; + Elf32_Shdr *shdr = &scn->s_shdr32; + + /* modify first section header, too! */ + elf_assert(scn); + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_info, phnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + phnum = PN_XNUM; + } + rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags); + rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags); + + for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) { + Elf64_Shdr *shdr = &scn->s_shdr64; + size_t scn_align = 1; + off_t len; + + elf_assert(scn->s_index == shnum); + + *flag |= scn->s_scn_flags; + + if (scn->s_index == SHN_UNDEF) { + rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags); + if (layout) { + rewrite(shdr->sh_offset, 0, scn->s_shdr_flags); + rewrite(shdr->sh_size, 0, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags); + } + *flag |= scn->s_shdr_flags; + continue; + } + if (shdr->sh_type == SHT_NULL) { + *flag |= scn->s_shdr_flags; + continue; + } + + len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag); + if (len == -1) { + return -1; + } + + /* + * Never override the program's choice. + */ + if (shdr->sh_entsize == 0) { + entsize = scn_entsize(elf, version, shdr->sh_type); + if (entsize > 1) { + rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); + } + } + + if (layout) { + align(off, scn_align); + rewrite(shdr->sh_offset, off, scn->s_shdr_flags); + rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags); + rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags); + + if (shdr->sh_type != SHT_NOBITS) { + off += (size_t)len; + } + } + else if ((size_t)len > shdr->sh_size) { + seterr(ERROR_SCN2SMALL); + return -1; + } + else { + Elf_Scn *scn2; + size_t end1, end2; + + end1 = shdr->sh_offset; + if (shdr->sh_type != SHT_NOBITS) { + end1 += shdr->sh_size; + } + if (!allow_overlap && shdr->sh_offset < off) { + /* + * check for overlapping sections + */ + for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) { + if (scn2 == scn) { + break; + } + end2 = scn2->s_shdr64.sh_offset; + if (scn2->s_shdr64.sh_type != SHT_NOBITS) { + end2 += scn2->s_shdr64.sh_size; + } + if (end1 > scn2->s_shdr64.sh_offset + && end2 > shdr->sh_offset) { + seterr(ERROR_SCN_OVERLAP); + return -1; + } + } + } + if (off < end1) { + off = end1; + } + } + *flag |= scn->s_shdr_flags; + } + + if (shnum) { + entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR); + elf_assert(entsize); + if (layout) { + align(off, align_addr); + rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags); + off += shnum * entsize; + } + else { + off = max(off, ehdr->e_shoff + shnum * entsize); + } + } + else { + entsize = 0; + if (layout) { + rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags); + } + } + if (shnum >= SHN_LORESERVE) { + Elf_Scn *scn = elf->e_scn_1; + Elf64_Shdr *shdr = &scn->s_shdr64; + + elf_assert(scn->s_index == 0); + rewrite(shdr->sh_size, shnum, scn->s_shdr_flags); + *flag |= scn->s_shdr_flags; + shnum = 0; + } + rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags); + rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags); + + rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags); + rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags); + rewrite(ehdr->e_version, version, elf->e_ehdr_flags); + + *flag |= elf->e_ehdr_flags; + + return off; +} + +#endif /* __LIBELF64 */ + +#define ptrinside(p,a,l) ((p)>=(a)&&(p)<(a)+(l)) +#define newptr(p,o,n) ((p)=((p)-(o))+(n)) + +static int +_elf_update_pointers(Elf *elf, char *outbuf, size_t len) { + Elf_Scn *scn; + Scn_Data *sd; + char *data, *rawdata; + + elf_assert(elf); + elf_assert(elf->e_data); + elf_assert(!elf->e_parent); + elf_assert(!elf->e_unmap_data); + elf_assert(elf->e_kind == ELF_K_ELF); + elf_assert(len >= EI_NIDENT); + + /* resize memory images */ + if (len <= elf->e_dsize) { + /* don't shorten the memory image */ + data = elf->e_data; + } + else if ((data = (char*)realloc(elf->e_data, len))) { + elf->e_dsize = len; + } + else { + seterr(ERROR_IO_2BIG); + return -1; + } + if (elf->e_rawdata == elf->e_data) { + /* update frozen raw image */ + memcpy(data, outbuf, len); + elf->e_data = elf->e_rawdata = data; + /* cooked data is stored outside the raw image */ + return 0; + } + if (elf->e_rawdata) { + /* update raw image */ + if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) { + seterr(ERROR_IO_2BIG); + return -1; + } + memcpy(rawdata, outbuf, len); + elf->e_rawdata = rawdata; + } + if (data == elf->e_data) { + /* nothing more to do */ + return 0; + } + /* adjust internal pointers */ + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + if ((sd = scn->s_data_1)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_memdata && !sd->sd_free_data) { + elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize)); + if (sd->sd_data.d_buf == sd->sd_memdata) { + newptr(sd->sd_memdata, elf->e_data, data); + sd->sd_data.d_buf = sd->sd_memdata; + } + else { + newptr(sd->sd_memdata, elf->e_data, data); + } + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_memdata && sd->sd_free_data) { + size_t off, len; + + if (elf->e_class == ELFCLASS32) { + off = scn->s_shdr32.sh_offset; + len = scn->s_shdr32.sh_size; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + off = scn->s_shdr64.sh_offset; + len = scn->s_shdr64.sh_size; + } +#endif /* __LIBELF64 */ + else { + seterr(ERROR_UNIMPLEMENTED); + return -1; + } + if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) { + seterr(ERROR_IO_2BIG); + return -1; + } + memcpy(rawdata, outbuf + off, len); + if (sd->sd_data.d_buf == sd->sd_memdata) { + sd->sd_data.d_buf = rawdata; + } + sd->sd_memdata = rawdata; + } + } + } + elf->e_data = data; + return 0; +} + +#undef ptrinside +#undef newptr + +static off_t +_elf32_write(Elf *elf, char *outbuf, size_t len) { + Elf32_Ehdr *ehdr; + Elf32_Shdr *shdr; + Elf_Scn *scn; + Scn_Data *sd; + Elf_Data src; + Elf_Data dst; + unsigned encode; + + elf_assert(len); + elf_assert(elf->e_ehdr); + ehdr = (Elf32_Ehdr*)elf->e_ehdr; + encode = ehdr->e_ident[EI_DATA]; + + src.d_buf = ehdr; + src.d_type = ELF_T_EHDR; + src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf; + dst.d_size = ehdr->e_ehsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (elf->e_phnum) { + src.d_buf = elf->e_phdr; + src.d_type = ELF_T_PHDR; + src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf + ehdr->e_phoff; + dst.d_size = elf->e_phnum * ehdr->e_phentsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + } + + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + + src.d_buf = &scn->s_uhdr; + src.d_type = ELF_T_SHDR; + src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR); + src.d_version = EV_CURRENT; + dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize; + dst.d_size = ehdr->e_shentsize; + dst.d_version = ehdr->e_version; + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (scn->s_index == SHN_UNDEF) { + continue; + } + shdr = &scn->s_shdr32; + if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) { + continue; + } + /* XXX: this is probably no longer necessary */ + if (scn->s_data_1 && !elf_getdata(scn, NULL)) { + return -1; + } + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + src = sd->sd_data; + if (!src.d_size) { + continue; + } + if (!src.d_buf) { + seterr(ERROR_NULLBUF); + return -1; + } + dst.d_buf = outbuf + shdr->sh_offset + src.d_off; + dst.d_size = src.d_size; + dst.d_version = ehdr->e_version; + if (valid_type(src.d_type)) { + size_t tmp; + + tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1); + if (tmp == (size_t)-1) { + return -1; + } + dst.d_size = tmp; + } + else { + src.d_type = ELF_T_BYTE; + } + if (!elf32_xlatetof(&dst, &src, encode)) { + return -1; + } + } + } + + /* cleanup */ + if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) { + return -1; + } + /* NOTE: ehdr is no longer valid! */ + ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr); + elf->e_encoding = ehdr->e_ident[EI_DATA]; + elf->e_version = ehdr->e_ident[EI_VERSION]; + elf->e_elf_flags &= ~ELF_F_DIRTY; + elf->e_ehdr_flags &= ~ELF_F_DIRTY; + elf->e_phdr_flags &= ~ELF_F_DIRTY; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + scn->s_scn_flags &= ~ELF_F_DIRTY; + scn->s_shdr_flags &= ~ELF_F_DIRTY; + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + sd->sd_data_flags &= ~ELF_F_DIRTY; + } + if (elf->e_readable) { + shdr = &scn->s_shdr32; + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + } + } + elf->e_size = len; + return len; +} + +#if __LIBELF64 + +static off_t +_elf64_write(Elf *elf, char *outbuf, size_t len) { + Elf64_Ehdr *ehdr; + Elf64_Shdr *shdr; + Elf_Scn *scn; + Scn_Data *sd; + Elf_Data src; + Elf_Data dst; + unsigned encode; + + elf_assert(len); + elf_assert(elf->e_ehdr); + ehdr = (Elf64_Ehdr*)elf->e_ehdr; + encode = ehdr->e_ident[EI_DATA]; + + src.d_buf = ehdr; + src.d_type = ELF_T_EHDR; + src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf; + dst.d_size = ehdr->e_ehsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (elf->e_phnum) { + src.d_buf = elf->e_phdr; + src.d_type = ELF_T_PHDR; + src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR); + src.d_version = _elf_version; + dst.d_buf = outbuf + ehdr->e_phoff; + dst.d_size = elf->e_phnum * ehdr->e_phentsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + } + + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(scn->s_elf == elf); + + src.d_buf = &scn->s_uhdr; + src.d_type = ELF_T_SHDR; + src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR); + src.d_version = EV_CURRENT; + dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize; + dst.d_size = ehdr->e_shentsize; + dst.d_version = ehdr->e_version; + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + + if (scn->s_index == SHN_UNDEF) { + continue; + } + shdr = &scn->s_shdr64; + if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) { + continue; + } + /* XXX: this is probably no longer necessary */ + if (scn->s_data_1 && !elf_getdata(scn, NULL)) { + return -1; + } + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + src = sd->sd_data; + if (!src.d_size) { + continue; + } + if (!src.d_buf) { + seterr(ERROR_NULLBUF); + return -1; + } + dst.d_buf = outbuf + shdr->sh_offset + src.d_off; + dst.d_size = src.d_size; + dst.d_version = ehdr->e_version; + if (valid_type(src.d_type)) { + size_t tmp; + + tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1); + if (tmp == (size_t)-1) { + return -1; + } + dst.d_size = tmp; + } + else { + src.d_type = ELF_T_BYTE; + } + if (!elf64_xlatetof(&dst, &src, encode)) { + return -1; + } + } + } + + /* cleanup */ + if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) { + return -1; + } + /* NOTE: ehdr is no longer valid! */ + ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr); + elf->e_encoding = ehdr->e_ident[EI_DATA]; + elf->e_version = ehdr->e_ident[EI_VERSION]; + elf->e_elf_flags &= ~ELF_F_DIRTY; + elf->e_ehdr_flags &= ~ELF_F_DIRTY; + elf->e_phdr_flags &= ~ELF_F_DIRTY; + for (scn = elf->e_scn_1; scn; scn = scn->s_link) { + scn->s_scn_flags &= ~ELF_F_DIRTY; + scn->s_shdr_flags &= ~ELF_F_DIRTY; + for (sd = scn->s_data_1; sd; sd = sd->sd_link) { + sd->sd_data_flags &= ~ELF_F_DIRTY; + } + if (elf->e_readable) { + shdr = &scn->s_shdr64; + scn->s_type = shdr->sh_type; + scn->s_size = shdr->sh_size; + scn->s_offset = shdr->sh_offset; + } + } + elf->e_size = len; + return len; +} + +#endif /* __LIBELF64 */ + +static int +xwrite(int fd, char *buffer, size_t len) { + size_t done = 0; + size_t n; + + while (done < len) { + n = write(fd, buffer + done, len - done); + if (n == 0) { + /* file system full */ + return -1; + } + else if (n != (size_t)-1) { + /* some bytes written, continue */ + done += n; + } + else if (errno != EAGAIN && errno != EINTR) { + /* real error */ + return -1; + } + } + return 0; +} + +static off_t +_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) { + char *buf; + off_t err; + + elf_assert(len); +#if HAVE_FTRUNCATE + ftruncate(fd, 0); +#endif /* HAVE_FTRUNCATE */ +#if HAVE_MMAP + /* + * Make sure the file is (at least) len bytes long + */ +#if HAVE_FTRUNCATE + lseek(fd, (off_t)len, SEEK_SET); + if (ftruncate(fd, len)) { +#else /* HAVE_FTRUNCATE */ + { +#endif /* HAVE_FTRUNCATE */ + if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) { + seterr(ERROR_IO_SEEK); + return -1; + } + if (xwrite(fd, "", 1)) { + seterr(ERROR_IO_WRITE); + return -1; + } + } + buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buf != (char*)-1) { + if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) { + memset(buf, _elf_fill, len); + } + err = _elf_write(elf, buf, len); + munmap(buf, len); + return err; + } +#endif /* HAVE_MMAP */ + if (!(buf = (char*)malloc(len))) { + seterr(ERROR_MEM_OUTBUF); + return -1; + } + memset(buf, _elf_fill, len); + err = _elf_write(elf, buf, len); + if (err != -1 && (size_t)err == len) { + if (lseek(fd, (off_t)0, SEEK_SET)) { + seterr(ERROR_IO_SEEK); + err = -1; + } + else if (xwrite(fd, buf, len)) { + seterr(ERROR_IO_WRITE); + err = -1; + } + } + free(buf); + return err; +} + +off_t +elf_update(Elf *elf, Elf_Cmd cmd) { + unsigned flag; + off_t len; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (cmd == ELF_C_WRITE) { + if (!elf->e_writable) { + seterr(ERROR_RDONLY); + return -1; + } + if (elf->e_disabled) { + seterr(ERROR_FDDISABLED); + return -1; + } + } + else if (cmd != ELF_C_NULL) { + seterr(ERROR_INVALID_CMD); + return -1; + } + + if (!elf->e_ehdr) { + seterr(ERROR_NOEHDR); + } + else if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + } + else if (elf->e_class == ELFCLASS32) { + len = _elf32_layout(elf, &flag); + if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) { + len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write); + } + return len; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + len = _elf64_layout(elf, &flag); + if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) { + len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write); + } + return len; + } +#endif /* __LIBELF64 */ + else if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return -1; +} diff --git a/external/libelf/src/verdef.h b/external/libelf/src/verdef.h new file mode 100644 index 00000000..e17f6826 --- /dev/null +++ b/external/libelf/src/verdef.h @@ -0,0 +1,241 @@ +/* + * verdef.h - copy versioning information. + * Copyright (C) 2001 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef lint +static const char verdef_h_rcsid[] = "@(#) $Id: verdef.h,v 1.13 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +#if VER_DEF_CURRENT != 1 +#error libelf currently does not support VER_DEF_CURRENT != 1 +#endif /* VER_DEF_CURRENT != 1 */ + +#if TOFILE + +static void +__store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u32L(dst->vda_name, src->vda_name); + __store_u32L(dst->vda_next, src->vda_next); + } + else { + __store_u32M(dst->vda_name, src->vda_name); + __store_u32M(dst->vda_next, src->vda_next); + } +} + +static void +__store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u16L(dst->vd_version, src->vd_version); + __store_u16L(dst->vd_flags, src->vd_flags); + __store_u16L(dst->vd_ndx, src->vd_ndx); + __store_u16L(dst->vd_cnt, src->vd_cnt); + __store_u32L(dst->vd_hash, src->vd_hash); + __store_u32L(dst->vd_aux, src->vd_aux); + __store_u32L(dst->vd_next, src->vd_next); + } + else { + __store_u16M(dst->vd_version, src->vd_version); + __store_u16M(dst->vd_flags, src->vd_flags); + __store_u16M(dst->vd_ndx, src->vd_ndx); + __store_u16M(dst->vd_cnt, src->vd_cnt); + __store_u32M(dst->vd_hash, src->vd_hash); + __store_u32M(dst->vd_aux, src->vd_aux); + __store_u32M(dst->vd_next, src->vd_next); + } +} + +typedef verdaux_mtype verdaux_stype; +typedef verdaux_ftype verdaux_dtype; +typedef verdef_mtype verdef_stype; +typedef verdef_ftype verdef_dtype; +typedef align_mtype verdef_atype; + +#define copy_verdaux_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verdaux_tmptodst(d, s, e) __store_verdaux((d), (s), (e)) +#define copy_verdef_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verdef_tmptodst(d, s, e) __store_verdef((d), (s), (e)) + +#define translator_suffix _tof + +#else /* TOFILE */ + +static void +__load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vda_name = __load_u32L(src->vda_name); + dst->vda_next = __load_u32L(src->vda_next); + } + else { + dst->vda_name = __load_u32M(src->vda_name); + dst->vda_next = __load_u32M(src->vda_next); + } +} + +static void +__load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vd_version = __load_u16L(src->vd_version); + dst->vd_flags = __load_u16L(src->vd_flags); + dst->vd_ndx = __load_u16L(src->vd_ndx); + dst->vd_cnt = __load_u16L(src->vd_cnt); + dst->vd_hash = __load_u32L(src->vd_hash); + dst->vd_aux = __load_u32L(src->vd_aux); + dst->vd_next = __load_u32L(src->vd_next); + } + else { + dst->vd_version = __load_u16M(src->vd_version); + dst->vd_flags = __load_u16M(src->vd_flags); + dst->vd_ndx = __load_u16M(src->vd_ndx); + dst->vd_cnt = __load_u16M(src->vd_cnt); + dst->vd_hash = __load_u32M(src->vd_hash); + dst->vd_aux = __load_u32M(src->vd_aux); + dst->vd_next = __load_u32M(src->vd_next); + } +} + +typedef verdaux_ftype verdaux_stype; +typedef verdaux_mtype verdaux_dtype; +typedef verdef_ftype verdef_stype; +typedef verdef_mtype verdef_dtype; +typedef align_ftype verdef_atype; + +#define copy_verdaux_srctotmp(d, s, e) __load_verdaux((d), (s), (e)) +#define copy_verdaux_tmptodst(d, s, e) (*(d) = *(s)) +#define copy_verdef_srctotmp(d, s, e) __load_verdef((d), (s), (e)) +#define copy_verdef_tmptodst(d, s, e) (*(d) = *(s)) + +#define translator_suffix _tom + +#endif /* TOFILE */ + +#define cat3(a,b,c) a##b##c +#define xlt3(p,e,s) cat3(p,e,s) +#define xltprefix(x) xlt3(x,_,class_suffix) +#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix) + +static size_t +xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) { + size_t off; + + if (sizeof(verdef_stype) != sizeof(verdef_dtype) + || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) { + /* never happens for ELF v1 and Verneed v1 */ + seterr(ERROR_UNIMPLEMENTED); + return (size_t)-1; + } + /* size translation shortcut */ + if (dst == NULL) { + return n; + } + if (src == NULL) { + seterr(ERROR_NULLBUF); + return (size_t)-1; + } + off = 0; + while (off + sizeof(verdef_stype) <= n) { + const verdef_stype *svd; + verdef_dtype *dvd; + verdef_mtype vd; + size_t acount; + size_t aoff; + + /* + * check for proper alignment + */ + if (off % sizeof(verdef_atype)) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svd = (verdef_stype*)(src + off); + dvd = (verdef_dtype*)(dst + off); + copy_verdef_srctotmp(&vd, svd, enc); + if (vd.vd_version < 1 + || vd.vd_version > VER_DEF_CURRENT) { + seterr(ERROR_VERDEF_VERSION); + return (size_t)-1; + } + if (vd.vd_cnt < 1 + || vd.vd_aux == 0) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + copy_verdef_tmptodst(dvd, &vd, enc); + /* + * copy aux array + */ + aoff = off + vd.vd_aux; + for (acount = 0; acount < vd.vd_cnt; acount++) { + const verdaux_stype *svda; + verdaux_dtype *dvda; + verdaux_mtype vda; + + /* + * are we still inside the buffer limits? + */ + if (aoff + sizeof(verdaux_stype) > n) { + break; + } + /* + * check for proper alignment + */ + if (aoff % sizeof(verdef_atype)) { + seterr(ERROR_VERDEF_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svda = (verdaux_stype*)(src + aoff); + dvda = (verdaux_dtype*)(dst + aoff); + copy_verdaux_srctotmp(&vda, svda, enc); + copy_verdaux_tmptodst(dvda, &vda, enc); + /* + * advance to next verdaux + */ + if (vda.vda_next == 0) { + /* end of list */ + break; + } + aoff += vda.vda_next; + } + /* + * advance to next verdef + */ + if (vd.vd_next == 0) { + /* end of list */ + break; + } + off += vd.vd_next; + } + return n; +} + +size_t +translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verdef(dst, src, n, ELFDATA2LSB); +} + +size_t +translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verdef(dst, src, n, ELFDATA2MSB); +} diff --git a/external/libelf/src/verdef_32_tof.c b/external/libelf/src/verdef_32_tof.c new file mode 100644 index 00000000..efca6ee9 --- /dev/null +++ b/external/libelf/src/verdef_32_tof.c @@ -0,0 +1,53 @@ +/* +verdef_32_tof.c - copy 32-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include +#include + +#if __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_32_tof.c,v 1.5 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +typedef Elf32_Verdaux verdaux_mtype; +typedef Elf32_Verdef verdef_mtype; +typedef Elf32_Vernaux vernaux_mtype; +typedef Elf32_Verneed verneed_mtype; +typedef Elf32_Word align_mtype; + +typedef __ext_Elf32_Verdaux verdaux_ftype; +typedef __ext_Elf32_Verdef verdef_ftype; +typedef __ext_Elf32_Vernaux vernaux_ftype; +typedef __ext_Elf32_Verneed verneed_ftype; +typedef __ext_Elf32_Word align_ftype; + +#define class_suffix 32 + +#undef TOFILE +#define TOFILE 1 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF_SYMBOL_VERSIONS */ diff --git a/external/libelf/src/verdef_32_tom.c b/external/libelf/src/verdef_32_tom.c new file mode 100644 index 00000000..f0efd0f9 --- /dev/null +++ b/external/libelf/src/verdef_32_tom.c @@ -0,0 +1,53 @@ +/* +verdef_32_tom.c - copy 32-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include +#include + +#if __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_32_tom.c,v 1.5 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +typedef Elf32_Verdaux verdaux_mtype; +typedef Elf32_Verdef verdef_mtype; +typedef Elf32_Vernaux vernaux_mtype; +typedef Elf32_Verneed verneed_mtype; +typedef Elf32_Word align_mtype; + +typedef __ext_Elf32_Verdaux verdaux_ftype; +typedef __ext_Elf32_Verdef verdef_ftype; +typedef __ext_Elf32_Vernaux vernaux_ftype; +typedef __ext_Elf32_Verneed verneed_ftype; +typedef __ext_Elf32_Word align_ftype; + +#define class_suffix 32 + +#undef TOFILE +#define TOFILE 0 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF_SYMBOL_VERSIONS */ diff --git a/external/libelf/src/verdef_64_tof.c b/external/libelf/src/verdef_64_tof.c new file mode 100644 index 00000000..16b903e6 --- /dev/null +++ b/external/libelf/src/verdef_64_tof.c @@ -0,0 +1,53 @@ +/* +verdef_64_tof.c - copy 64-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include +#include + +#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_64_tof.c,v 1.5 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +typedef Elf64_Verdaux verdaux_mtype; +typedef Elf64_Verdef verdef_mtype; +typedef Elf64_Vernaux vernaux_mtype; +typedef Elf64_Verneed verneed_mtype; +typedef Elf64_Word align_mtype; + +typedef __ext_Elf64_Verdaux verdaux_ftype; +typedef __ext_Elf64_Verdef verdef_ftype; +typedef __ext_Elf64_Vernaux vernaux_ftype; +typedef __ext_Elf64_Verneed verneed_ftype; +typedef __ext_Elf64_Word align_ftype; + +#define class_suffix 64 + +#undef TOFILE +#define TOFILE 1 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */ diff --git a/external/libelf/src/verdef_64_tom.c b/external/libelf/src/verdef_64_tom.c new file mode 100644 index 00000000..183524ef --- /dev/null +++ b/external/libelf/src/verdef_64_tom.c @@ -0,0 +1,53 @@ +/* +verdef_64_tom.c - copy 64-bit versioning information. +Copyright (C) 2001 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include +#include + +#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS + +#ifndef lint +static const char rcsid[] = "@(#) $Id: verdef_64_tom.c,v 1.5 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +typedef Elf64_Verdaux verdaux_mtype; +typedef Elf64_Verdef verdef_mtype; +typedef Elf64_Vernaux vernaux_mtype; +typedef Elf64_Verneed verneed_mtype; +typedef Elf64_Word align_mtype; + +typedef __ext_Elf64_Verdaux verdaux_ftype; +typedef __ext_Elf64_Verdef verdef_ftype; +typedef __ext_Elf64_Vernaux vernaux_ftype; +typedef __ext_Elf64_Verneed verneed_ftype; +typedef __ext_Elf64_Word align_ftype; + +#define class_suffix 64 + +#undef TOFILE +#define TOFILE 0 + +/* + * Include shared code + */ +#include "verdef.h" +#include "verneed.h" + +#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */ diff --git a/external/libelf/src/verneed.h b/external/libelf/src/verneed.h new file mode 100644 index 00000000..54f0f060 --- /dev/null +++ b/external/libelf/src/verneed.h @@ -0,0 +1,245 @@ +/* + * verneed.h - copy versioning information. + * Copyright (C) 2001 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef lint +static const char verneed_h_rcsid[] = "@(#) $Id: verneed.h,v 1.13 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +#if VER_NEED_CURRENT != 1 +#error libelf currently does not support VER_NEED_CURRENT != 1 +#endif /* VER_NEED_CURRENT != 1 */ + +#if TOFILE + +static void +__store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u32L(dst->vna_hash, src->vna_hash); + __store_u16L(dst->vna_flags, src->vna_flags); + __store_u16L(dst->vna_other, src->vna_other); + __store_u32L(dst->vna_name, src->vna_name); + __store_u32L(dst->vna_next, src->vna_next); + } + else { + __store_u32M(dst->vna_hash, src->vna_hash); + __store_u16M(dst->vna_flags, src->vna_flags); + __store_u16M(dst->vna_other, src->vna_other); + __store_u32M(dst->vna_name, src->vna_name); + __store_u32M(dst->vna_next, src->vna_next); + } +} + +static void +__store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + __store_u16L(dst->vn_version, src->vn_version); + __store_u16L(dst->vn_cnt, src->vn_cnt); + __store_u32L(dst->vn_file, src->vn_file); + __store_u32L(dst->vn_aux, src->vn_aux); + __store_u32L(dst->vn_next, src->vn_next); + } + else { + __store_u16M(dst->vn_version, src->vn_version); + __store_u16M(dst->vn_cnt, src->vn_cnt); + __store_u32M(dst->vn_file, src->vn_file); + __store_u32M(dst->vn_aux, src->vn_aux); + __store_u32M(dst->vn_next, src->vn_next); + } +} + +typedef vernaux_mtype vernaux_stype; +typedef vernaux_ftype vernaux_dtype; +typedef verneed_mtype verneed_stype; +typedef verneed_ftype verneed_dtype; +typedef align_mtype verneed_atype; + +#define copy_vernaux_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_vernaux_tmptodst(d, s, e) __store_vernaux((d), (s), (e)) +#define copy_verneed_srctotmp(d, s, e) (*(d) = *(s)) +#define copy_verneed_tmptodst(d, s, e) __store_verneed((d), (s), (e)) + +#define translator_suffix _tof + +#else /* TOFILE */ + +static void +__load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vna_hash = __load_u32L(src->vna_hash); + dst->vna_flags = __load_u16L(src->vna_flags); + dst->vna_other = __load_u16L(src->vna_other); + dst->vna_name = __load_u32L(src->vna_name); + dst->vna_next = __load_u32L(src->vna_next); + } + else { + dst->vna_hash = __load_u32M(src->vna_hash); + dst->vna_flags = __load_u16M(src->vna_flags); + dst->vna_other = __load_u16M(src->vna_other); + dst->vna_name = __load_u32M(src->vna_name); + dst->vna_next = __load_u32M(src->vna_next); + } +} + +static void +__load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) { + if (enc == ELFDATA2LSB) { + dst->vn_version = __load_u16L(src->vn_version); + dst->vn_cnt = __load_u16L(src->vn_cnt); + dst->vn_file = __load_u32L(src->vn_file); + dst->vn_aux = __load_u32L(src->vn_aux); + dst->vn_next = __load_u32L(src->vn_next); + } + else { + dst->vn_version = __load_u16M(src->vn_version); + dst->vn_cnt = __load_u16M(src->vn_cnt); + dst->vn_file = __load_u32M(src->vn_file); + dst->vn_aux = __load_u32M(src->vn_aux); + dst->vn_next = __load_u32M(src->vn_next); + } +} + +typedef vernaux_ftype vernaux_stype; +typedef vernaux_mtype vernaux_dtype; +typedef verneed_ftype verneed_stype; +typedef verneed_mtype verneed_dtype; +typedef align_ftype verneed_atype; + +#define copy_vernaux_srctotmp(d, s, e) __load_vernaux((d), (s), (e)) +#define copy_vernaux_tmptodst(d, s, e) (*(d) = *(s)) +#define copy_verneed_srctotmp(d, s, e) __load_verneed((d), (s), (e)) +#define copy_verneed_tmptodst(d, s, e) (*(d) = *(s)) + +#define translator_suffix _tom + +#endif /* TOFILE */ + +#define cat3(a,b,c) a##b##c +#define xlt3(p,e,s) cat3(p,e,s) +#define xltprefix(x) xlt3(x,_,class_suffix) +#define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix) + +static size_t +xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) { + size_t off; + + if (sizeof(verneed_stype) != sizeof(verneed_dtype) + || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) { + /* never happens for ELF v1 and Verneed v1 */ + seterr(ERROR_UNIMPLEMENTED); + return (size_t)-1; + } + /* size translation shortcut */ + if (dst == NULL) { + return n; + } + if (src == NULL) { + seterr(ERROR_NULLBUF); + return (size_t)-1; + } + off = 0; + while (off + sizeof(verneed_stype) <= n) { + const verneed_stype *svn; + verneed_dtype *dvn; + verneed_mtype vn; + size_t acount; + size_t aoff; + + /* + * check for proper alignment + */ + if (off % sizeof(verneed_atype)) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svn = (verneed_stype*)(src + off); + dvn = (verneed_dtype*)(dst + off); + copy_verneed_srctotmp(&vn, svn, enc); + if (vn.vn_version < 1 + || vn.vn_version > VER_NEED_CURRENT) { + seterr(ERROR_VERNEED_VERSION); + return (size_t)-1; + } + if (vn.vn_cnt < 1 + || vn.vn_aux == 0) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + copy_verneed_tmptodst(dvn, &vn, enc); + /* + * copy aux array + */ + aoff = off + vn.vn_aux; + for (acount = 0; acount < vn.vn_cnt; acount++) { + const vernaux_stype *svna; + vernaux_dtype *dvna; + vernaux_mtype vna; + + /* + * are we still inside the buffer limits? + */ + if (aoff + sizeof(vernaux_stype) > n) { + break; + } + /* + * check for proper alignment + */ + if (aoff % sizeof(verneed_atype)) { + seterr(ERROR_VERNEED_FORMAT); + return (size_t)-1; + } + /* + * copy and check src + */ + svna = (vernaux_stype*)(src + aoff); + dvna = (vernaux_dtype*)(dst + aoff); + copy_vernaux_srctotmp(&vna, svna, enc); + copy_vernaux_tmptodst(dvna, &vna, enc); + /* + * advance to next vernaux + */ + if (vna.vna_next == 0) { + /* end of list */ + break; + } + aoff += vna.vna_next; + } + /* + * advance to next verneed + */ + if (vn.vn_next == 0) { + /* end of list */ + break; + } + off += vn.vn_next; + } + return n; +} + +size_t +translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verneed(dst, src, n, ELFDATA2LSB); +} + +size_t +translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) { + return xlt_verneed(dst, src, n, ELFDATA2MSB); +} diff --git a/external/libelf/src/version.c b/external/libelf/src/version.c new file mode 100644 index 00000000..7a901d31 --- /dev/null +++ b/external/libelf/src/version.c @@ -0,0 +1,44 @@ +/* + * version.c - implementation of the elf_version(3) function. + * Copyright (C) 1995 - 1998, 2007 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: version.c,v 1.8 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +unsigned +elf_version(unsigned ver) { + const char *s; + unsigned tmp; + + if ((s = getenv("LIBELF_SANITY_CHECKS"))) { + _elf_sanity_checks = (int)strtol(s, (char**)NULL, 0); + } + if (ver == EV_NONE) { + return EV_CURRENT; + } + if (!valid_version(ver)) { + seterr(ERROR_UNKNOWN_VERSION); + return EV_NONE; + } + tmp = _elf_version == EV_NONE ? EV_CURRENT : _elf_version; + _elf_version = ver; + return tmp; +} diff --git a/external/libelf/src/x.elfext.c b/external/libelf/src/x.elfext.c new file mode 100644 index 00000000..cbd35395 --- /dev/null +++ b/external/libelf/src/x.elfext.c @@ -0,0 +1,190 @@ +/* + * x.elfext.c -- handle ELF format extensions + * Copyright (C) 2002 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.elfext.c,v 1.5 2009/07/07 17:57:43 michael Exp $"; +#endif /* lint */ + +int +elf_getphdrnum(Elf *elf, size_t *resultp) { + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return -1; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + if (resultp) { + *resultp = elf->e_phnum; + } + return 0; +} + +int +elf_getshdrnum(Elf *elf, size_t *resultp) { + size_t num = 0; + Elf_Scn *scn; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return -1; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + if ((scn = elf->e_scn_n)) { + num = scn->s_index + 1; + } + if (resultp) { + *resultp = num; + } + return 0; +} + +int +elf_getshdrstrndx(Elf *elf, size_t *resultp) { + size_t num = 0; + size_t dummy; + Elf_Scn *scn; + + if (!elf) { + return -1; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (resultp == NULL) { + resultp = &dummy; /* handle NULL pointer gracefully */ + } + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return -1; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return -1; + } + if (elf->e_class == ELFCLASS32) { + num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return -1; + } + if (num != SHN_XINDEX) { + *resultp = num; + return 0; + } + /* + * look at first section header + */ + if (!(scn = elf->e_scn_1)) { + seterr(ERROR_NOSUCHSCN); + return -1; + } + elf_assert(scn->s_magic == SCN_MAGIC); +#if __LIBELF64 + if (elf->e_class == ELFCLASS64) { + *resultp = scn->s_shdr64.sh_link; + return 0; + } +#endif /* __LIBELF64 */ + *resultp = scn->s_shdr32.sh_link; + return 0; +} + +int +elf_getphnum(Elf *elf, size_t *resultp) { + return elf_getphdrnum(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS; +} + +int +elf_getshnum(Elf *elf, size_t *resultp) { + return elf_getshdrnum(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS; +} + +int +elf_getshstrndx(Elf *elf, size_t *resultp) { + return elf_getshdrstrndx(elf, resultp) ? LIBELF_FAILURE : LIBELF_SUCCESS; +} + +int +elfx_update_shstrndx(Elf *elf, size_t value) { + size_t extvalue = 0; + Elf_Scn *scn; + + if (!elf) { + return LIBELF_FAILURE; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (value >= SHN_LORESERVE) { + extvalue = value; + value = SHN_XINDEX; + } + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return LIBELF_FAILURE; + } + if (!elf->e_ehdr && !_elf_cook(elf)) { + return LIBELF_FAILURE; + } + if (!(scn = _elf_first_scn(elf))) { + return LIBELF_FAILURE; + } + elf_assert(scn->s_magic == SCN_MAGIC); + if (elf->e_class == ELFCLASS32) { + ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx = value; + scn->s_shdr32.sh_link = extvalue; + } +#if __LIBELF64 + else if (elf->e_class == ELFCLASS64) { + ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx = value; + scn->s_shdr64.sh_link = extvalue; + } +#endif /* __LIBELF64 */ + else { + if (valid_class(elf->e_class)) { + seterr(ERROR_UNIMPLEMENTED); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return LIBELF_FAILURE; + } + elf->e_ehdr_flags |= ELF_F_DIRTY; + scn->s_shdr_flags |= ELF_F_DIRTY; + return LIBELF_SUCCESS; +} diff --git a/external/libelf/src/x.movscn.c b/external/libelf/src/x.movscn.c new file mode 100644 index 00000000..4f3d9d24 --- /dev/null +++ b/external/libelf/src/x.movscn.c @@ -0,0 +1,112 @@ +/* +x.movscn.c - implementation of the elfx_movscn(3) function. +Copyright (C) 1995 - 2001, 2003 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.movscn.c,v 1.14 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +size_t +elfx_movscn(Elf *elf, Elf_Scn *scn, Elf_Scn *after) { + Elf_Scn *prev; + Elf_Scn *tmp; + int off; + + if (!elf || !scn || !after) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(after->s_magic == SCN_MAGIC); + if (scn->s_elf != elf || after->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + if (scn == after || scn == after->s_link) { + /* nothing to do */ + return scn->s_index; + } + + /* + * Find previous section. + */ + prev = NULL; + for (tmp = elf->e_scn_1; tmp->s_link; tmp = tmp->s_link) { + if (tmp->s_link == scn) { + prev = tmp; + break; + } + } + elf_assert(prev != NULL); + + /* + * Update section indices + */ + off = 0; + for (tmp = elf->e_scn_1; tmp; tmp = tmp->s_link) { + if (off) { + tmp->s_index += off; + } + if (tmp == after) { + off++; + } + else if (tmp == scn) { + off--; + } + } + elf_assert(off == 0); + + /* + * Move section. + */ + prev->s_link = scn->s_link; + scn->s_link = after->s_link; + after->s_link = scn; + scn->s_index = after->s_index + 1; + if (elf->e_scn_n == scn) { + elf->e_scn_n = prev; + } + else if (elf->e_scn_n == after) { + elf->e_scn_n = scn; + } + +#if ENABLE_DEBUG + /* + * Check section indices + */ + tmp = elf->e_scn_1; + elf_assert(tmp->s_index == 0); + while (tmp->s_link) { + elf_assert(tmp->s_link->s_index == tmp->s_index + 1); + tmp = tmp->s_link; + } +#endif /* ENABLE_DEBUG */ + + return scn->s_index; +} diff --git a/external/libelf/src/x.remscn.c b/external/libelf/src/x.remscn.c new file mode 100644 index 00000000..d04816ec --- /dev/null +++ b/external/libelf/src/x.remscn.c @@ -0,0 +1,119 @@ +/* +x.remscn.c - implementation of the elfx_remscn(3) function. +Copyright (C) 1995 - 2001, 2003 Michael Riepe + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include + +#ifndef lint +static const char rcsid[] = "@(#) $Id: x.remscn.c,v 1.15 2008/05/23 08:15:35 michael Exp $"; +#endif /* lint */ + +size_t +elfx_remscn(Elf *elf, Elf_Scn *scn) { + Elf_Scn *pscn; + Scn_Data *sd; + Scn_Data *tmp; + size_t index; + + if (!elf || !scn) { + return SHN_UNDEF; + } + elf_assert(elf->e_magic == ELF_MAGIC); + if (elf->e_kind != ELF_K_ELF) { + seterr(ERROR_NOTELF); + return SHN_UNDEF; + } + elf_assert(scn->s_magic == SCN_MAGIC); + elf_assert(elf->e_ehdr); + if (scn->s_elf != elf) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + elf_assert(elf->e_scn_1); + if (scn == elf->e_scn_1) { + seterr(ERROR_NULLSCN); + return SHN_UNDEF; + } + + /* + * Find previous section. + */ + for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) { + if (pscn->s_link == scn) { + break; + } + } + if (pscn->s_link != scn) { + seterr(ERROR_ELFSCNMISMATCH); + return SHN_UNDEF; + } + + /* + * Unlink section. + */ + if (elf->e_scn_n == scn) { + elf->e_scn_n = pscn; + } + pscn->s_link = scn->s_link; + index = scn->s_index; + + /* + * Free section descriptor and data. + */ + for (sd = scn->s_data_1; sd; sd = tmp) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + tmp = sd->sd_link; + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if ((sd = scn->s_rawdata)) { + elf_assert(sd->sd_magic == DATA_MAGIC); + elf_assert(sd->sd_scn == scn); + if (sd->sd_free_data && sd->sd_memdata) { + free(sd->sd_memdata); + } + if (sd->sd_freeme) { + free(sd); + } + } + if (scn->s_freeme) { + elf_assert(scn->s_index > 0); + free(scn); + } + + /* + * Adjust section indices. + */ + for (scn = pscn->s_link; scn; scn = scn->s_link) { + elf_assert(scn->s_index > index); + scn->s_index--; + } + + /* + * Adjust section count in ELF header + */ + if (_elf_update_shnum(elf, elf->e_scn_n->s_index + 1)) { + return SHN_UNDEF; + } + return index; +} diff --git a/external/libhidapi/AUTHORS.txt b/external/libhidapi/AUTHORS.txt new file mode 100644 index 00000000..e08cb161 --- /dev/null +++ b/external/libhidapi/AUTHORS.txt @@ -0,0 +1,18 @@ + +HIDAPI Authors: + +Alan Ott : + Original Author and Maintainer + Linux, Windows, and Mac implementations + +Ludovic Rousseau : + Formatting for Doxygen documentation + Bug fixes + Correctness fixes + +libusb/hidapi Team: + Development/maintainance since June 4th 2019 + +For a comprehensive list of contributions, see the commit list at github: + https://github.com/libusb/hidapi/commits/master + diff --git a/external/libhidapi/HACKING.txt b/external/libhidapi/HACKING.txt new file mode 100644 index 00000000..761d4b65 --- /dev/null +++ b/external/libhidapi/HACKING.txt @@ -0,0 +1,15 @@ +This file is mostly for the maintainer. + +1. Build hidapi.dll +2. Build hidtest.exe in DEBUG and RELEASE +3. Commit all + +4. Run the Following + export VERSION=0.1.0 + export TAG_NAME=hidapi-$VERSION + git tag $TAG_NAME + git archive --format zip --prefix $TAG_NAME/ $TAG_NAME >../$TAG_NAME.zip +5. Test the zip file. +6. Run the following: + git push origin $TAG_NAME + diff --git a/external/libhidapi/LICENSE-bsd.txt b/external/libhidapi/LICENSE-bsd.txt new file mode 100644 index 00000000..538cdf95 --- /dev/null +++ b/external/libhidapi/LICENSE-bsd.txt @@ -0,0 +1,26 @@ +Copyright (c) 2010, Alan Ott, Signal 11 Software +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Signal 11 Software nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/external/libhidapi/LICENSE-gpl3.txt b/external/libhidapi/LICENSE-gpl3.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/external/libhidapi/LICENSE-gpl3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/external/libhidapi/LICENSE-orig.txt b/external/libhidapi/LICENSE-orig.txt new file mode 100644 index 00000000..e3f33808 --- /dev/null +++ b/external/libhidapi/LICENSE-orig.txt @@ -0,0 +1,9 @@ + HIDAPI - Multi-Platform library for + communication with HID devices. + + Copyright 2009, Alan Ott, Signal 11 Software. + All Rights Reserved. + + This software may be used by anyone for any reason so + long as the copyright notice in the source files + remains intact. diff --git a/external/libhidapi/LICENSE.txt b/external/libhidapi/LICENSE.txt new file mode 100644 index 00000000..e1676d4c --- /dev/null +++ b/external/libhidapi/LICENSE.txt @@ -0,0 +1,13 @@ +HIDAPI can be used under one of three licenses. + +1. The GNU General Public License, version 3.0, in LICENSE-gpl3.txt +2. A BSD-Style License, in LICENSE-bsd.txt. +3. The more liberal original HIDAPI license. LICENSE-orig.txt + +The license chosen is at the discretion of the user of HIDAPI. For example: +1. An author of GPL software would likely use HIDAPI under the terms of the +GPL. + +2. An author of commercial closed-source software would likely use HIDAPI +under the terms of the BSD-style license or the original HIDAPI license. + diff --git a/external/libhidapi/README.md b/external/libhidapi/README.md new file mode 100644 index 00000000..f5582d7a --- /dev/null +++ b/external/libhidapi/README.md @@ -0,0 +1,380 @@ +## HIDAPI library for Windows, Linux, FreeBSD and macOS + +| CI instance | Status | +|----------------------|--------| +| `macOS master` | [![Build Status](https://travis-ci.org/libusb/hidapi.svg?branch=master)](https://travis-ci.org/libusb/hidapi) | +| `Windows master` | [![Build status](https://ci.appveyor.com/api/projects/status/r482aevuigmi86rk/branch/master?svg=true)](https://ci.appveyor.com/project/Youw/hidapi/branch/master) | +| `Linux/BSD, last build (branch/PR)` | [![builds.sr.ht status](https://builds.sr.ht/~qbicz/hidapi.svg)](https://builds.sr.ht/~qbicz/hidapi?) | + +HIDAPI is a multi-platform library which allows an application to interface +with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS. +HIDAPI can be either built as a shared library (`.so`, `.dll` or `.dylib`) or +can be embedded directly into a target application by adding a single source +file (per platform) and a single header. + +HIDAPI library was originally developed by Alan Ott ([signal11](https://github.com/signal11)). + +It was moved to [libusb/hidapi](https://github.com/libusb/hidapi) on June 4th, 2019, in order to merge important bugfixes and continue development of the library. + +## Table of Contents + +* [About](#about) +* [What Does the API Look Like?](#what-does-the-api-look-like) +* [License](#license) +* [Download](#download) +* [Build Instructions](#build-instructions) + * [Prerequisites](#prerequisites) + * [Linux](#linux) + * [FreeBSD](#freebsd) + * [Mac](#mac) + * [Windows](#windows) + * [Building HIDAPI into a shared library on Unix Platforms](#building-hidapi-into-a-shared-library-on-unix-platforms) + * [Building the manual way on Unix platforms](#building-the-manual-way-on-unix-platforms) + * [Building on Windows](#building-on-windows) +* [Cross Compiling](#cross-compiling) + * [Prerequisites](#prerequisites-1) + * [Building HIDAPI](#building-hidapi) + +## About + +HIDAPI has five back-ends: +* Windows (using `hid.dll`) +* Linux/hidraw (using the Kernel's hidraw driver) +* Linux/libusb (using libusb-1.0) +* FreeBSD (using libusb-1.0) +* Mac (using IOHidManager) + +On Linux, either the hidraw or the libusb back-end can be used. There are +tradeoffs, and the functionality supported is slightly different. + +__Linux/hidraw__ (`linux/hid.c`): + +This back-end uses the hidraw interface in the Linux kernel, and supports +both USB and Bluetooth HID devices. It requires kernel version at least 2.6.39 +to build. In addition, it will only communicate with devices which have hidraw +nodes associated with them. +Keyboards, mice, and some other devices which are blacklisted from having +hidraw nodes will not work. Fortunately, for nearly all the uses of hidraw, +this is not a problem. + +__Linux/FreeBSD/libusb__ (`libusb/hid.c`): + +This back-end uses libusb-1.0 to communicate directly to a USB device. This +back-end will of course not work with Bluetooth devices. + +HIDAPI also comes with a Test GUI. The Test GUI is cross-platform and uses +Fox Toolkit . It will build on every platform +which HIDAPI supports. Since it relies on a 3rd party library, building it +is optional but recommended because it is so useful when debugging hardware. + +## What Does the API Look Like? +The API provides the most commonly used HID functions including sending +and receiving of input, output, and feature reports. The sample program, +which communicates with a heavily hacked up version of the Microchip USB +Generic HID sample looks like this (with error checking removed for +simplicity): + +**Warning: Only run the code you understand, and only when it conforms to the +device spec. Writing data at random to your HID devices can break them.** + +```c +#ifdef WIN32 +#include +#endif +#include +#include +#include "hidapi.h" + +#define MAX_STR 255 + +int main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + wchar_t wstr[MAX_STR]; + hid_device *handle; + int i; + + // Initialize the hidapi library + res = hid_init(); + + // Open the device using the VID, PID, + // and optionally the Serial number. + handle = hid_open(0x4d8, 0x3f, NULL); + + // Read the Manufacturer String + res = hid_get_manufacturer_string(handle, wstr, MAX_STR); + wprintf(L"Manufacturer String: %s\n", wstr); + + // Read the Product String + res = hid_get_product_string(handle, wstr, MAX_STR); + wprintf(L"Product String: %s\n", wstr); + + // Read the Serial Number String + res = hid_get_serial_number_string(handle, wstr, MAX_STR); + wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr); + + // Read Indexed String 1 + res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); + wprintf(L"Indexed String 1: %s\n", wstr); + + // Toggle LED (cmd 0x80). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x80; + res = hid_write(handle, buf, 65); + + // Request state (cmd 0x81). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x81; + res = hid_write(handle, buf, 65); + + // Read requested state + res = hid_read(handle, buf, 65); + + // Print out the returned buffer. + for (i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + // Close the device + hid_close(handle); + + // Finalize the hidapi library + res = hid_exit(); + + return 0; +} +``` + +You can also use [hidtest/test.c](hidtest/test.c) +as a starting point for your applications. + + +## License +HIDAPI may be used by one of three licenses as outlined in [LICENSE.txt](LICENSE.txt). + +## Download +HIDAPI can be downloaded from GitHub +```sh +git clone git://github.com/libusb/hidapi.git +``` + +## Build Instructions + +This section is long. Don't be put off by this. It's not long because it's +complicated to build HIDAPI; it's quite the opposite. This section is long +because of the flexibility of HIDAPI and the large number of ways in which +it can be built and used. You will likely pick a single build method. + +HIDAPI can be built in several different ways. If you elect to build a +shared library, you will need to build it from the HIDAPI source +distribution. If you choose instead to embed HIDAPI directly into your +application, you can skip the building and look at the provided platform +Makefiles for guidance. These platform Makefiles are located in `linux/`, +`libusb/`, `mac/` and `windows/` and are called `Makefile-manual`. In addition, +Visual Studio projects are provided. Even if you're going to embed HIDAPI +into your project, it is still beneficial to build the example programs. + + +### Prerequisites: + +#### Linux: +On Linux, you will need to install development packages for libudev, +libusb and optionally Fox-toolkit (for the test GUI). On +Debian/Ubuntu systems these can be installed by running: +```sh +sudo apt-get install libudev-dev libusb-1.0-0-dev libfox-1.6-dev +``` + +If you downloaded the source directly from the git repository (using +git clone), you'll need Autotools: +```sh +sudo apt-get install autotools-dev autoconf automake libtool +``` + +#### FreeBSD: +On FreeBSD you will need to install GNU make, libiconv, and +optionally Fox-Toolkit (for the test GUI). This is done by running +the following: +```sh +pkg_add -r gmake libiconv fox16 +``` + +If you downloaded the source directly from the git repository (using +git clone), you'll need Autotools: +```sh +pkg_add -r autotools +``` + +#### Mac: +On Mac, you will need to install Fox-Toolkit if you wish to build +the Test GUI. There are two ways to do this, and each has a slight +complication. Which method you use depends on your use case. + +If you wish to build the Test GUI just for your own testing on your +own computer, then the easiest method is to install Fox-Toolkit +using ports: +```sh +sudo port install fox +``` + +If you wish to build the TestGUI app bundle to redistribute to +others, you will need to install Fox-toolkit from source. This is +because the version of fox that gets installed using ports uses the +ports X11 libraries which are not compatible with the Apple X11 +libraries. If you install Fox with ports and then try to distribute +your built app bundle, it will simply fail to run on other systems. +To install Fox-Toolkit manually, download the source package from +, extract it, and run the following from +within the extracted source: +```sh +./configure && make && make install +``` + +#### Windows: +On Windows, if you want to build the test GUI, you will need to get +the `hidapi-externals.zip` package from the download site. This +contains pre-built binaries for Fox-toolkit. Extract +`hidapi-externals.zip` just outside of hidapi, so that +hidapi-externals and hidapi are on the same level, as shown: +``` + Parent_Folder + | + +hidapi + +hidapi-externals +``` +Again, this step is not required if you do not wish to build the +test GUI. + + +### Building HIDAPI into a shared library on Unix Platforms: + +On Unix-like systems such as Linux, FreeBSD, macOS, and even Windows, using +MinGW or Cygwin, the easiest way to build a standard system-installed shared +library is to use the GNU Autotools build system. If you checked out the +source from the git repository, run the following: + +```sh +./bootstrap +./configure +make +make install # as root, or using sudo +``` + +If you downloaded a source package (i.e.: if you did not run git clone), you +can skip the `./bootstrap` step. + +`./configure` can take several arguments which control the build. The two most +likely to be used are: +```sh + --enable-testgui + Enable build of the Test GUI. This requires Fox toolkit to + be installed. Instructions for installing Fox-Toolkit on + each platform are in the Prerequisites section above. + + --prefix=/usr + Specify where you want the output headers and libraries to + be installed. The example above will put the headers in + /usr/include and the binaries in /usr/lib. The default is to + install into /usr/local which is fine on most systems. +``` +### Building the manual way on Unix platforms: + +Manual Makefiles are provided mostly to give the user and idea what it takes +to build a program which embeds HIDAPI directly inside of it. These should +really be used as examples only. If you want to build a system-wide shared +library, use the Autotools method described above. + +To build HIDAPI using the manual Makefiles, change to the directory +of your platform and run make. For example, on Linux run: +```sh +cd linux/ +make -f Makefile-manual +``` + +To build the Test GUI using the manual makefiles: +```sh +cd testgui/ +make -f Makefile-manual +``` + +### Building on Windows: + +To build the HIDAPI DLL on Windows using Visual Studio, build the `.sln` file +in the `windows/` directory. + +To build the Test GUI on windows using Visual Studio, build the `.sln` file in +the `testgui/` directory. + +To build HIDAPI using MinGW or Cygwin using Autotools, use the instructions +in the section [Building HIDAPI into a shared library on Unix Platforms](#building-hidapi-into-a-shared-library-on-unix-platforms) +above. Note that building the Test GUI with MinGW or Cygwin will +require the Windows procedure in the [Prerequisites](#prerequisites-1) section +above (i.e.: `hidapi-externals.zip`). + +To build HIDAPI using MinGW using the Manual Makefiles, see the section +[Building the manual way on Unix platforms](#building-the-manual-way-on-unix-platforms) +above. + +HIDAPI can also be built using the Windows DDK (now also called the Windows +Driver Kit or WDK). This method was originally required for the HIDAPI build +but not anymore. However, some users still prefer this method. It is not as +well supported anymore but should still work. Patches are welcome if it does +not. To build using the DDK: + + 1. Install the Windows Driver Kit (WDK) from Microsoft. + 2. From the Start menu, in the Windows Driver Kits folder, select Build + Environments, then your operating system, then the x86 Free Build + Environment (or one that is appropriate for your system). + 3. From the console, change directory to the `windows/ddk_build/` directory, + which is part of the HIDAPI distribution. + 4. Type build. + 5. You can find the output files (DLL and LIB) in a subdirectory created + by the build system which is appropriate for your environment. On + Windows XP, this directory is `objfre_wxp_x86/i386`. + +## Cross Compiling + +This section talks about cross compiling HIDAPI for Linux using Autotools. +This is useful for using HIDAPI on embedded Linux targets. These +instructions assume the most raw kind of embedded Linux build, where all +prerequisites will need to be built first. This process will of course vary +based on your embedded Linux build system if you are using one, such as +OpenEmbedded or Buildroot. + +For the purpose of this section, it will be assumed that the following +environment variables are exported. +```sh +$ export STAGING=$HOME/out +$ export HOST=arm-linux +``` + +`STAGING` and `HOST` can be modified to suit your setup. + +### Prerequisites + +Note that the build of libudev is the very basic configuration. + +Build libusb. From the libusb source directory, run: +```sh +./configure --host=$HOST --prefix=$STAGING +make +make install +``` + +Build libudev. From the libudev source directory, run: +```sh +./configure --disable-gudev --disable-introspection --disable-hwdb \ + --host=$HOST --prefix=$STAGING +make +make install +``` + +### Building HIDAPI + +Build HIDAPI: +``` +PKG_CONFIG_DIR= \ +PKG_CONFIG_LIBDIR=$STAGING/lib/pkgconfig:$STAGING/share/pkgconfig \ +PKG_CONFIG_SYSROOT_DIR=$STAGING \ +./configure --host=$HOST --prefix=$STAGING +``` diff --git a/external/libhidapi/include/hidapi/hidapi.h b/external/libhidapi/include/hidapi/hidapi.h new file mode 100644 index 00000000..4102e6c1 --- /dev/null +++ b/external/libhidapi/include/hidapi/hidapi.h @@ -0,0 +1,446 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + https://github.com/libusb/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. + * Valid on the Mac implementation if and only if the device + is a USB HID device. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id is set to 0 then any vendor matches. + If @p product_id is set to 0 then any product matches. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device_info, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + This function sets the return value of hid_error(). + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + This function sets the return value of hid_error(). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length); + + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read within + the timeout period, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read and + the handle is in non-blocking mode, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Set the first byte of @p data[] to the Report ID of the + report to be read. Make sure to allow space for this + extra byte in @p data[]. Upon return, the first byte will + still contain the Report ID, and the report data will + start in data[1]. + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read, or set it to zero + if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read plus + one for the report ID (which is still in the first + byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length); + + /** @brief Get a input report from a HID device. + + Set the first byte of @p data[] to the Report ID of the + report to be read. Make sure to allow space for this + extra byte in @p data[]. Upon return, the first byte will + still contain the Report ID, and the report data will + start in data[1]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read, or set it to zero + if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read plus + one for the report ID (which is still in the first + byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + This function sets the return value of hid_error(). + + @ingroup API + @param dev A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + Whether a function sets the last error is noted in its + documentation. These functions will reset the last error + to NULL before their execution. + + Strings returned from hid_error() must not be freed by the user! + + This function is thread-safe, and error messages are thread-local. + + @ingroup API + @param dev A device handle returned from hid_open(), + or NULL to get the last non-device-specific error + (e.g. for errors in hid_open() itself). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/libhidapi/libhidapi.vcxproj b/external/libhidapi/libhidapi.vcxproj new file mode 100644 index 00000000..125592ad --- /dev/null +++ b/external/libhidapi/libhidapi.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + 16.0 + Win32Proj + {17054837-6ae6-44d7-914d-9625edef4657} + libhidapi + 10.0 + + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + include\hidapi + 4267 + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include\hidapi + 4267 + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + include\hidapi + 4267 + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include\hidapi + 4267 + + + true + true + true + + + + + + \ No newline at end of file diff --git a/external/libhidapi/libhidapi.vcxproj.filters b/external/libhidapi/libhidapi.vcxproj.filters new file mode 100644 index 00000000..926eb584 --- /dev/null +++ b/external/libhidapi/libhidapi.vcxproj.filters @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/external/libhidapi/src/hid.c b/external/libhidapi/src/hid.c new file mode 100644 index 00000000..799b3555 --- /dev/null +++ b/external/libhidapi/src/hid.c @@ -0,0 +1,1019 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + https://github.com/libusb/hidapi . +********************************************************/ + +#include + +#ifndef _NTDEF_ +typedef LONG NTSTATUS; +#endif + +#ifdef __MINGW32__ +#include +#include +#endif + +#ifdef __CYGWIN__ +#include +#define _wcsdup wcsdup +#endif + +/* The maximum number of characters that can be passed into the + HidD_Get*String() functions without it failing.*/ +#define MAX_STRING_WCHARS 0xFFF + +/*#define HIDAPI_USE_DDK*/ + +#ifdef __cplusplus +extern "C" { +#endif + #include + #include + #ifdef HIDAPI_USE_DDK + #include + #endif + + /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */ + #define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) + #define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include +#include + + +#include "hidapi.h" + +#undef MIN +#define MIN(x,y) ((x) < (y)? (x): (y)) + +#ifdef _MSC_VER + /* Thanks Microsoft, but I know how to use strncpy(). */ + #pragma warning(disable:4996) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HIDAPI_USE_DDK + /* Since we're not building with the DDK, and the HID header + files aren't part of the SDK, we have to define all this + stuff here. In lookup_functions(), the function pointers + defined below are set. */ + typedef struct _HIDD_ATTRIBUTES{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + + typedef USHORT USAGE; + typedef struct _HIDP_CAPS { + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + USHORT fields_not_used_by_hidapi[10]; + } HIDP_CAPS, *PHIDP_CAPS; + typedef void* PHIDP_PREPARSED_DATA; + #define HIDP_STATUS_SUCCESS 0x110000 + + typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib); + typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data); + typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data); + typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps); + typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers); + + static HidD_GetAttributes_ HidD_GetAttributes; + static HidD_GetSerialNumberString_ HidD_GetSerialNumberString; + static HidD_GetManufacturerString_ HidD_GetManufacturerString; + static HidD_GetProductString_ HidD_GetProductString; + static HidD_SetFeature_ HidD_SetFeature; + static HidD_GetFeature_ HidD_GetFeature; + static HidD_GetInputReport_ HidD_GetInputReport; + static HidD_GetIndexedString_ HidD_GetIndexedString; + static HidD_GetPreparsedData_ HidD_GetPreparsedData; + static HidD_FreePreparsedData_ HidD_FreePreparsedData; + static HidP_GetCaps_ HidP_GetCaps; + static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers; + + static HMODULE lib_handle = NULL; + static BOOLEAN initialized = FALSE; +#endif /* HIDAPI_USE_DDK */ + +struct hid_device_ { + HANDLE device_handle; + BOOL blocking; + USHORT output_report_length; + size_t input_report_length; + void *last_error_str; + DWORD last_error_num; + BOOL read_pending; + char *read_buf; + OVERLAPPED ol; +}; + +static hid_device *new_hid_device() +{ + hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); + dev->device_handle = INVALID_HANDLE_VALUE; + dev->blocking = TRUE; + dev->output_report_length = 0; + dev->input_report_length = 0; + dev->last_error_str = NULL; + dev->last_error_num = 0; + dev->read_pending = FALSE; + dev->read_buf = NULL; + memset(&dev->ol, 0, sizeof(dev->ol)); + dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + CloseHandle(dev->ol.hEvent); + CloseHandle(dev->device_handle); + LocalFree(dev->last_error_str); + free(dev->read_buf); + free(dev); +} + +static void register_error(hid_device *dev, const char *op) +{ + WCHAR *ptr, *msg; + + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPVOID)&msg, 0/*sz*/, + NULL); + + /* Get rid of the CR and LF that FormatMessage() sticks at the + end of the message. Thanks Microsoft! */ + ptr = msg; + while (*ptr) { + if (*ptr == '\r') { + *ptr = 0x0000; + break; + } + ptr++; + } + + /* Store the message off in the Device entry so that + the hid_error() function can pick it up. */ + LocalFree(dev->last_error_str); + dev->last_error_str = msg; +} + +#ifndef HIDAPI_USE_DDK +static int lookup_functions() +{ + lib_handle = LoadLibraryA("hid.dll"); + if (lib_handle) { +#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; + RESOLVE(HidD_GetAttributes); + RESOLVE(HidD_GetSerialNumberString); + RESOLVE(HidD_GetManufacturerString); + RESOLVE(HidD_GetProductString); + RESOLVE(HidD_SetFeature); + RESOLVE(HidD_GetFeature); + RESOLVE(HidD_GetInputReport); + RESOLVE(HidD_GetIndexedString); + RESOLVE(HidD_GetPreparsedData); + RESOLVE(HidD_FreePreparsedData); + RESOLVE(HidP_GetCaps); + RESOLVE(HidD_SetNumInputBuffers); +#undef RESOLVE + } + else + return -1; + + return 0; +} +#endif + +static HANDLE open_device(const char *path, BOOL open_rw) +{ + HANDLE handle; + DWORD desired_access = (open_rw)? (GENERIC_WRITE | GENERIC_READ): 0; + DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + + handle = CreateFileA(path, + desired_access, + share_mode, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ + 0); + + return handle; +} + +int HID_API_EXPORT hid_init(void) +{ +#ifndef HIDAPI_USE_DDK + if (!initialized) { + if (lookup_functions() < 0) { + hid_exit(); + return -1; + } + initialized = TRUE; + } +#endif + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ +#ifndef HIDAPI_USE_DDK + if (lib_handle) + FreeLibrary(lib_handle); + lib_handle = NULL; + initialized = FALSE; +#endif + return 0; +} + +struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + BOOL res; + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + /* Windows objects for interacting with the driver. */ + GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; + SP_DEVINFO_DATA devinfo_data; + SP_DEVICE_INTERFACE_DATA device_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; + HDEVINFO device_info_set = INVALID_HANDLE_VALUE; + int device_index = 0; + int i; + + if (hid_init() < 0) + return NULL; + + /* Initialize the Windows objects. */ + memset(&devinfo_data, 0x0, sizeof(devinfo_data)); + devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); + device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + /* Get information for all the devices belonging to the HID class. */ + device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + /* Iterate over each device in the HID class, looking for the right one. */ + + for (;;) { + HANDLE write_handle = INVALID_HANDLE_VALUE; + DWORD required_size = 0; + HIDD_ATTRIBUTES attrib; + + res = SetupDiEnumDeviceInterfaces(device_info_set, + NULL, + &InterfaceClassGuid, + device_index, + &device_interface_data); + + if (!res) { + /* A return of FALSE from this function means that + there are no more devices. */ + break; + } + + /* Call with 0-sized detail size, and let the function + tell us how long the detail struct needs to be. The + size is put in &required_size. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + NULL, + 0, + &required_size, + NULL); + + /* Allocate a long enough structure for device_interface_detail_data. */ + device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); + device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + + /* Get the detailed data for this device. The detail data gives us + the device path for this device, which is then passed into + CreateFile() to get a handle to the device. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + device_interface_detail_data, + required_size, + NULL, + NULL); + + if (!res) { + /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); + Continue to the next device. */ + goto cont; + } + + /* Make sure this device is of Setup Class "HIDClass" and has a + driver bound to it. */ + for (i = 0; ; i++) { + char driver_name[256]; + + /* Populate devinfo_data. This function will return failure + when there are no more interfaces left. */ + res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); + if (!res) + goto cont; + + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (!res) + goto cont; + + if ((strcmp(driver_name, "HIDClass") == 0) || + (strcmp(driver_name, "Mouse") == 0) || + (strcmp(driver_name, "Keyboard") == 0)) { + /* See if there's a driver bound. */ + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (res) + break; + } + } + + //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); + + /* Open a handle to the device */ + write_handle = open_device(device_interface_detail_data->DevicePath, FALSE); + + /* Check validity of write_handle. */ + if (write_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + //register_error(dev, "CreateFile"); + goto cont_close; + } + + + /* Get the Vendor ID and Product ID for this device. */ + attrib.Size = sizeof(HIDD_ATTRIBUTES); + HidD_GetAttributes(write_handle, &attrib); + //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + + /* Check the VID/PID to see if we should add this + device to the enumeration list. */ + if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && + (product_id == 0x0 || attrib.ProductID == product_id)) { + + #define WSTR_LEN 512 + const char *str; + struct hid_device_info *tmp; + PHIDP_PREPARSED_DATA pp_data = NULL; + HIDP_CAPS caps; + BOOLEAN res; + NTSTATUS nt_res; + wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ + size_t len; + + /* VID/PID match. Create the record. */ + tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Get the Usage Page and Usage for this device. */ + res = HidD_GetPreparsedData(write_handle, &pp_data); + if (res) { + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res == HIDP_STATUS_SUCCESS) { + cur_dev->usage_page = caps.UsagePage; + cur_dev->usage = caps.Usage; + } + + HidD_FreePreparsedData(pp_data); + } + + /* Fill out the record */ + cur_dev->next = NULL; + str = device_interface_detail_data->DevicePath; + if (str) { + len = strlen(str); + cur_dev->path = (char*) calloc(len+1, sizeof(char)); + strncpy(cur_dev->path, str, len+1); + cur_dev->path[len] = '\0'; + } + else + cur_dev->path = NULL; + + /* Serial Number */ + wstr[0]= 0x0000; + res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->serial_number = _wcsdup(wstr); + } + + /* Manufacturer String */ + wstr[0]= 0x0000; + res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->manufacturer_string = _wcsdup(wstr); + } + + /* Product String */ + wstr[0]= 0x0000; + res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->product_string = _wcsdup(wstr); + } + + /* VID/PID */ + cur_dev->vendor_id = attrib.VendorID; + cur_dev->product_id = attrib.ProductID; + + /* Release Number */ + cur_dev->release_number = attrib.VersionNumber; + + /* Interface Number. It can sometimes be parsed out of the path + on Windows if a device has multiple interfaces. See + http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or + search for "Hardware IDs for HID Devices" at MSDN. If it's not + in the path, it's set to -1. */ + cur_dev->interface_number = -1; + if (cur_dev->path) { + char *interface_component = strstr(cur_dev->path, "&mi_"); + if (interface_component) { + char *hex_str = interface_component + 4; + char *endptr = NULL; + cur_dev->interface_number = strtol(hex_str, &endptr, 16); + if (endptr == hex_str) { + /* The parsing failed. Set interface_number to -1. */ + cur_dev->interface_number = -1; + } + } + } + } + +cont_close: + CloseHandle(write_handle); +cont: + /* We no longer need the detail data. It can be freed */ + free(device_interface_detail_data); + + device_index++; + + } + + /* Close the device information handle. */ + SetupDiDestroyDeviceInfoList(device_info_set); + + return root; + +} + +void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) +{ + /* TODO: Merge this with the Linux version. This function is platform-independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + + +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* TODO: Merge this functions with the Linux version. This function should be platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) +{ + hid_device *dev; + HIDP_CAPS caps; + PHIDP_PREPARSED_DATA pp_data = NULL; + BOOLEAN res; + NTSTATUS nt_res; + + if (hid_init() < 0) { + return NULL; + } + + dev = new_hid_device(); + + /* Open a handle to the device */ + dev->device_handle = open_device(path, TRUE); + + /* Check validity of write_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { + /* System devices, such as keyboards and mice, cannot be opened in + read-write mode, because the system takes exclusive control over + them. This is to prevent keyloggers. However, feature reports + can still be sent and received. Retry opening the device, but + without read/write access. */ + dev->device_handle = open_device(path, FALSE); + + /* Check the validity of the limited device_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device, even without read-write mode. */ + register_error(dev, "CreateFile"); + goto err; + } + } + + /* Set the Input Report buffer size to 64 reports. */ + res = HidD_SetNumInputBuffers(dev->device_handle, 64); + if (!res) { + register_error(dev, "HidD_SetNumInputBuffers"); + goto err; + } + + /* Get the Input Report length for the device. */ + res = HidD_GetPreparsedData(dev->device_handle, &pp_data); + if (!res) { + register_error(dev, "HidD_GetPreparsedData"); + goto err; + } + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res != HIDP_STATUS_SUCCESS) { + register_error(dev, "HidP_GetCaps"); + goto err_pp_data; + } + dev->output_report_length = caps.OutputReportByteLength; + dev->input_report_length = caps.InputReportByteLength; + HidD_FreePreparsedData(pp_data); + + dev->read_buf = (char*) malloc(dev->input_report_length); + + return dev; + +err_pp_data: + HidD_FreePreparsedData(pp_data); +err: + free_hid_device(dev); + return NULL; +} + +int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + DWORD bytes_written; + BOOL res; + + OVERLAPPED ol; + unsigned char *buf; + memset(&ol, 0, sizeof(ol)); + + /* Make sure the right number of bytes are passed to WriteFile. Windows + expects the number of bytes which are in the _longest_ report (plus + one for the report number) bytes even if the data is a report + which is shorter than that. Windows gives us this value in + caps.OutputReportByteLength. If a user passes in fewer bytes than this, + create a temporary buffer which is the proper size. */ + if (length >= dev->output_report_length) { + /* The user passed the right number of bytes. Use the buffer as-is. */ + buf = (unsigned char *) data; + } else { + /* Create a temporary buffer and copy the user's data + into it, padding the rest with zeros. */ + buf = (unsigned char *) malloc(dev->output_report_length); + memcpy(buf, data, length); + memset(buf + length, 0, dev->output_report_length - length); + length = dev->output_report_length; + } + + res = WriteFile(dev->device_handle, buf, length, NULL, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + } + + /* Wait here until the write is done. This makes + hid_write() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + +end_of_function: + if (buf != data) + free(buf); + + return bytes_written; +} + + +int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + DWORD bytes_read = 0; + size_t copy_len = 0; + BOOL res; + + /* Copy the handle for convenience. */ + HANDLE ev = dev->ol.hEvent; + + if (!dev->read_pending) { + /* Start an Overlapped I/O read. */ + dev->read_pending = TRUE; + memset(dev->read_buf, 0, dev->input_report_length); + ResetEvent(ev); + res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* ReadFile() has failed. + Clean up and return error. */ + CancelIo(dev->device_handle); + dev->read_pending = FALSE; + goto end_of_function; + } + } + } + + if (milliseconds >= 0) { + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; + } + } + + /* Either WaitForSingleObject() told us that ReadFile has completed, or + we are in non-blocking mode. Get the number of bytes read. The actual + data has been copied to the data[] array which was passed to ReadFile(). */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + + /* Set pending back to false, even if GetOverlappedResult() returned error. */ + dev->read_pending = FALSE; + + if (res && bytes_read > 0) { + if (dev->read_buf[0] == 0x0) { + /* If report numbers aren't being used, but Windows sticks a report + number (0x0) on the beginning of the report anyway. To make this + work like the other platforms, and to make it work more like the + HID spec, we'll skip over this byte. */ + bytes_read--; + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf+1, copy_len); + } + else { + /* Copy the whole buffer, report number and all. */ + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf, copy_len); + } + } + +end_of_function: + if (!res) { + register_error(dev, "GetOverlappedResult"); + return -1; + } + + return copy_len; +} + +int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + return 0; /* Success */ +} + +int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length); + if (!res) { + register_error(dev, "HidD_SetFeature"); + return -1; + } + + return length; +} + + +int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + BOOL res; +#if 0 + res = HidD_GetFeature(dev->device_handle, data, length); + if (!res) { + register_error(dev, "HidD_GetFeature"); + return -1; + } + return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */ +#else + DWORD bytes_returned; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + res = DeviceIoControl(dev->device_handle, + IOCTL_HID_GET_FEATURE, + data, length, + data, length, + &bytes_returned, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Feature Report DeviceIoControl"); + return -1; + } + } + + /* Wait here until the write is done. This makes + hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { + /* The operation failed. */ + register_error(dev, "Send Feature Report GetOverLappedResult"); + return -1; + } + + /* bytes_returned does not include the first byte which contains the + report ID. The data buffer actually contains one more byte than + bytes_returned. */ + bytes_returned++; + + return bytes_returned; +#endif +} + + +int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length) +{ + BOOL res; +#if 0 + res = HidD_GetInputReport(dev->device_handle, data, length); + if (!res) { + register_error(dev, "HidD_GetInputReport"); + return -1; + } + return length; +#else + DWORD bytes_returned; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + res = DeviceIoControl(dev->device_handle, + IOCTL_HID_GET_INPUT_REPORT, + data, length, + data, length, + &bytes_returned, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Input Report DeviceIoControl"); + return -1; + } + } + + /* Wait here until the write is done. This makes + hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { + /* The operation failed. */ + register_error(dev, "Send Input Report GetOverLappedResult"); + return -1; + } + + /* bytes_returned does not include the first byte which contains the + report ID. The data buffer actually contains one more byte than + bytes_returned. */ + bytes_returned++; + + return bytes_returned; +#endif +} + +void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) +{ + if (!dev) + return; + CancelIo(dev->device_handle); + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetManufacturerString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetProductString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetSerialNumberString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetIndexedString"); + return -1; + } + + return 0; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + if (dev) { + if (dev->last_error_str == NULL) + return L"Success"; + return (wchar_t*)dev->last_error_str; + } + + // Global error messages are not (yet) implemented on Windows. + return L"hid_error for global errors is not implemented yet"; +} + + +/*#define PICPGM*/ +/*#define S11*/ +#define P32 +#ifdef S11 + unsigned short VendorID = 0xa0a0; + unsigned short ProductID = 0x0001; +#endif + +#ifdef P32 + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x3f; +#endif + + +#ifdef PICPGM + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x0033; +#endif + + +#if 0 +int __cdecl main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + /* Set up the command buffer. */ + memset(buf,0x00,sizeof(buf)); + buf[0] = 0; + buf[1] = 0x81; + + + /* Open the device. */ + int handle = open(VendorID, ProductID, L"12345"); + if (handle < 0) + printf("unable to open device\n"); + + + /* Toggle LED (cmd 0x80) */ + buf[1] = 0x80; + res = write(handle, buf, 65); + if (res < 0) + printf("Unable to write()\n"); + + /* Request state (cmd 0x81) */ + buf[1] = 0x81; + write(handle, buf, 65); + if (res < 0) + printf("Unable to write() (2)\n"); + + /* Read requested state */ + read(handle, buf, 65); + if (res < 0) + printf("Unable to read()\n"); + + /* Print out the returned buffer. */ + for (int i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + return 0; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/external/libusb/AUTHORS.txt b/external/libusb/AUTHORS.txt new file mode 100644 index 00000000..375ec6c2 --- /dev/null +++ b/external/libusb/AUTHORS.txt @@ -0,0 +1,16 @@ + +Library, Test Programs: + +Stephan Meyer, +Johannes Erdfelt, +Thomas Sailer, + +Drivers, Installer: + +Stephan Meyer, +Travis Robinson, + +Testing, Technical support: + +Xiaofan Chen, + diff --git a/external/libusb/COPYING_GPL.txt b/external/libusb/COPYING_GPL.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/external/libusb/COPYING_GPL.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/external/libusb/COPYING_LGPL.txt b/external/libusb/COPYING_LGPL.txt new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/external/libusb/COPYING_LGPL.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/external/libusb/README.in b/external/libusb/README.in new file mode 100644 index 00000000..e5721254 --- /dev/null +++ b/external/libusb/README.in @@ -0,0 +1,12 @@ + +This is libusb-win32 (http://libusb-win32.sourceforge.net) version @VERSION@. +Libusb-win32 is a library that allows userspace application to access USB +devices on Windows operation systems (Win2k, WinXP, Vista, Win7). +It is derived from and fully API compatible to libusb available at +http://libusb.sourceforge.net. + +For more information visit the project's web site at: + +http://libusb-win32.sourceforge.net +http://sourceforge.net/projects/libusb-win32 + diff --git a/external/libusb/include/lusb0_usb.h b/external/libusb/include/lusb0_usb.h new file mode 100644 index 00000000..f9d3e5ec --- /dev/null +++ b/external/libusb/include/lusb0_usb.h @@ -0,0 +1,429 @@ +#ifndef __LUSB0_USB__ +#define __LUSB0_USB__ + +#include + +/* + * 'interface' is defined somewhere in the Windows header files. This macro + * is deleted here to avoid conflicts and compile errors. + */ + +#ifdef interface +#undef interface +#endif + +/* + * PATH_MAX from limits.h can't be used on Windows if the dll and + * import libraries are build/used by different compilers + */ + +#define LIBUSB_PATH_MAX 512 + + +/* + * USB spec information + * + * This is all stuff grabbed from various USB specs and is pretty much + * not subject to change + */ + +/* + * Device and/or Interface Class codes + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_DATA 10 +#define USB_CLASS_VENDOR_SPEC 0xff + +/* + * Descriptor types + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 + +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHYSICAL 0x23 +#define USB_DT_HUB 0x29 + +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 + + +/* ensure byte-packed structures */ +#include + + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header +{ + unsigned char bLength; + unsigned char bDescriptorType; +}; + +/* String descriptor */ +struct usb_string_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; +}; + +/* HID descriptor */ +struct usb_hid_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdHID; + unsigned char bCountryCode; + unsigned char bNumDescriptors; +}; + +/* Endpoint descriptor */ +#define USB_MAXENDPOINTS 32 +struct usb_endpoint_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#ifndef __USBSPEC_H__ +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 +#endif + +/* Interface descriptor */ +#define USB_MAXINTERFACES 32 +struct usb_interface_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + struct usb_endpoint_descriptor *endpoint; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_MAXALTSETTING 128 /* Hard limit */ + +struct usb_interface +{ + struct usb_interface_descriptor *altsetting; + + int num_altsetting; +}; + +/* Configuration descriptor information.. */ +#define USB_MAXCONFIG 8 +struct usb_config_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; + + struct usb_interface *interface; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +/* Device descriptor */ +struct usb_device_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; +}; + +struct usb_ctrl_setup +{ + unsigned char bRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +}; + +/* + * Standard requests + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +/* 0x02 is reserved */ +#define USB_REQ_SET_FEATURE 0x03 +/* 0x04 is reserved */ +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + +/* + * Various libusb API related stuff + */ + +#define USB_ENDPOINT_IN 0x80 +#define USB_ENDPOINT_OUT 0x00 + +/* Error codes */ +#define USB_ERROR_BEGIN 500000 + +/* + * This is supposed to look weird. This file is generated from autoconf + * and I didn't want to make this too complicated. + */ +#define USB_LE16_TO_CPU(x) + +/* + * Device reset types for usb_reset_ex. + * http://msdn.microsoft.com/en-us/library/ff537269%28VS.85%29.aspx + * http://msdn.microsoft.com/en-us/library/ff537243%28v=vs.85%29.aspx + */ +#define USB_RESET_TYPE_RESET_PORT (1 << 0) +#define USB_RESET_TYPE_CYCLE_PORT (1 << 1) +#define USB_RESET_TYPE_FULL_RESET (USB_RESET_TYPE_CYCLE_PORT | USB_RESET_TYPE_RESET_PORT) + + +/* Data types */ +/* struct usb_device; */ +/* struct usb_bus; */ + +struct usb_device +{ + struct usb_device *next, *prev; + + char filename[LIBUSB_PATH_MAX]; + + struct usb_bus *bus; + + struct usb_device_descriptor descriptor; + struct usb_config_descriptor *config; + + void *dev; /* Darwin support */ + + unsigned char devnum; + + unsigned char num_children; + struct usb_device **children; +}; + +struct usb_bus +{ + struct usb_bus *next, *prev; + + char dirname[LIBUSB_PATH_MAX]; + + struct usb_device *devices; + unsigned long location; + + struct usb_device *root_dev; +}; + +/* Version information, Windows specific */ +struct usb_version +{ + struct + { + int major; + int minor; + int micro; + int nano; + } dll; + struct + { + int major; + int minor; + int micro; + int nano; + } driver; +}; + + +struct usb_dev_handle; +typedef struct usb_dev_handle usb_dev_handle; + +/* Variables */ +#ifndef __USB_C__ +#define usb_busses usb_get_busses() +#endif + + + +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Function prototypes */ + + /* usb.c */ + usb_dev_handle *usb_open(struct usb_device *dev); + int usb_close(usb_dev_handle *dev); + int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen); + int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, + size_t buflen); + + /* descriptors.c */ + int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, + void *buf, int size); + int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size); + + /* .c */ + int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, + int timeout); + int usb_set_configuration(usb_dev_handle *dev, int configuration); + int usb_claim_interface(usb_dev_handle *dev, int interface); + int usb_release_interface(usb_dev_handle *dev, int interface); + int usb_set_altinterface(usb_dev_handle *dev, int alternate); + int usb_resetep(usb_dev_handle *dev, unsigned int ep); + int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); + int usb_reset(usb_dev_handle *dev); + int usb_reset_ex(usb_dev_handle *dev, unsigned int reset_type); + + char *usb_strerror(void); + + void usb_init(void); + void usb_set_debug(int level); + int usb_find_busses(void); + int usb_find_devices(void); + struct usb_device *usb_device(usb_dev_handle *dev); + struct usb_bus *usb_get_busses(void); + + +#ifdef _WINDOWS_ + /* Windows specific functions */ + +#define LIBUSB_HAS_INSTALL_SERVICE_NP 1 + int usb_install_service_np(void); + void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 + int usb_uninstall_service_np(void); + void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_DRIVER_NP 1 + int usb_install_driver_np(const char *inf_file); + void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 + int usb_touch_inf_file_np(const char *inf_file); + void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 + int usb_install_needs_restart_np(void); + +#define LIBUSB_HAS_INSTALL_NP 1 + int usb_install_npW(HWND hwnd, HINSTANCE instance, LPCWSTR cmd_line, int starg_arg); + int usb_install_npA(HWND hwnd, HINSTANCE instance, LPCSTR cmd_line, int starg_arg); + #define usb_install_np usb_install_npA + void CALLBACK usb_install_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); +#endif + + const struct usb_version *usb_get_version(void); + + int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize); + int usb_bulk_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + + int usb_submit_async(void *context, char *bytes, int size); + int usb_reap_async(void *context, int timeout); + int usb_reap_async_nocancel(void *context, int timeout); + int usb_cancel_async(void *context); + int usb_free_async(void **context); + + +#ifdef __cplusplus +} +#endif + +#endif /* __LUSB0_USB__ */ diff --git a/external/libusb/libusb.vcxproj b/external/libusb/libusb.vcxproj new file mode 100644 index 00000000..ab0f529c --- /dev/null +++ b/external/libusb/libusb.vcxproj @@ -0,0 +1,166 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + 16.0 + Win32Proj + {22615ec5-9dbc-4538-9c01-2cd535b3810b} + libusb + 10.0 + libusb + + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + 4996 + include + + + true + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + 4996 + include + + + true + true + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + 4996 + include + + + true + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + 4996 + include + + + true + true + true + + + + + + \ No newline at end of file diff --git a/external/libusb/libusb.vcxproj.filters b/external/libusb/libusb.vcxproj.filters new file mode 100644 index 00000000..0fd41508 --- /dev/null +++ b/external/libusb/libusb.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/libusb/src/descriptors.c b/external/libusb/src/descriptors.c new file mode 100644 index 00000000..ba98839d --- /dev/null +++ b/external/libusb/src/descriptors.c @@ -0,0 +1,572 @@ +/* + * Parses descriptors + * + * Copyright (c) 2001 Johannes Erdfelt + * + * This library is covered by the LGPL, read LICENSE for details. + */ + +#include +#include +#include "usbi.h" + +int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, void *buf, int size) +{ + memset(buf, 0, size); + + return usb_control_msg(udev, ep | USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, + (type << 8) + index, 0, buf, size, 1000); +} + +int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size) +{ + memset(buf, 0, size); + + return usb_control_msg(udev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, + (type << 8) + index, 0, buf, size, 1000); +} + +int usb_parse_descriptor(unsigned char *source, char *description, void *dest) +{ + unsigned char *sp = source, *dp = dest; + uint16_t w; + uint32_t d; + char *cp; + + for (cp = description; *cp; cp++) + { + switch (*cp) + { + case 'b': /* 8-bit byte */ + *dp++ = *sp++; + break; + case 'w': /* 16-bit word, convert from little endian to CPU */ + w = (sp[1] << 8) | sp[0]; + sp += 2; + //dp += ((unsigned long)dp & 1); /* Align to word boundary */ + *((uint16_t *)dp) = w; + dp += 2; + break; + case 'd': /* 32-bit dword, convert from little endian to CPU */ + d = (sp[3] << 24) | (sp[2] << 16) | (sp[1] << 8) | sp[0]; + sp += 4; + //dp += ((unsigned long)dp & 2); /* Align to dword boundary */ + *((uint32_t *)dp) = d; + dp += 4; + break; + /* These two characters are undocumented and just a hack for Linux */ + case 'W': /* 16-bit word, keep CPU endianess */ + //dp += ((unsigned long)dp & 1); /* Align to word boundary */ + memcpy(dp, sp, 2); + sp += 2; + dp += 2; + break; + case 'D': /* 32-bit dword, keep CPU endianess */ + //dp += ((unsigned long)dp & 2); /* Align to dword boundary */ + memcpy(dp, sp, 4); + sp += 4; + dp += 4; + break; + } + } + + return (int)(sp - source); +} + +/* + * This code looks surprisingly similar to the code I wrote for the Linux + * kernel. It's not a coincidence :) + */ + +static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size) +{ + struct usb_descriptor_header header; + unsigned char *begin; + int parsed = 0, len, numskipped; + + usb_parse_descriptor(buffer, "bb", &header); + + /* Everything should be fine being passed into here, but we sanity */ + /* check JIC */ + if (header.bLength > size) + { + if (usb_debug >= 1) + fprintf(stderr, "ran out of descriptors parsing\n"); + return -1; + } + + if (header.bDescriptorType != USB_DT_ENDPOINT) + { + if (usb_debug >= 2) + fprintf(stderr, "unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X\n", + header.bDescriptorType, USB_DT_ENDPOINT); + return parsed; + } + + if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) + usb_parse_descriptor(buffer, "bbbbwbbb", endpoint); + else if (header.bLength >= ENDPOINT_DESC_LENGTH) + usb_parse_descriptor(buffer, "bbbbwb", endpoint); + + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + + /* Skip over the rest of the Class Specific or Vendor Specific */ + /* descriptors */ + begin = buffer; + numskipped = 0; + while (size >= DESC_HEADER_LENGTH) + { + usb_parse_descriptor(buffer, "bb", &header); + + if (header.bLength < 2) + { + if (usb_debug >= 1) + fprintf(stderr, "invalid descriptor length of %d\n", header.bLength); + return -1; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == USB_DT_ENDPOINT) || + (header.bDescriptorType == USB_DT_INTERFACE) || + (header.bDescriptorType == USB_DT_CONFIG) || + (header.bDescriptorType == USB_DT_DEVICE)) + break; + + if (usb_debug >= 1) + fprintf(stderr, "skipping descriptor 0x%X\n", header.bDescriptorType); + numskipped++; + + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + } + + if (numskipped && usb_debug >= 2) + fprintf(stderr, "skipped %d class/vendor specific endpoint descriptors\n", numskipped); + + /* Copy any unknown descriptors into a storage area for drivers */ + /* to later parse */ + len = (int)(buffer - begin); + if (!len) + { + endpoint->extra = NULL; + endpoint->extralen = 0; + return parsed; + } + + endpoint->extra = malloc(len); + if (!endpoint->extra) + { + if (usb_debug >= 1) + fprintf(stderr, "couldn't allocate memory for endpoint extra descriptors\n"); + endpoint->extralen = 0; + return parsed; + } + + memcpy(endpoint->extra, begin, len); + endpoint->extralen = len; + + return parsed; +} + +static int usb_parse_interface(struct usb_interface *interface, + unsigned char *buffer, int size) +{ + int i, len, numskipped, retval, parsed = 0; + struct usb_descriptor_header header; + struct usb_interface_descriptor *ifp; + unsigned char *begin; + + interface->num_altsetting = 0; + + while (size >= INTERFACE_DESC_LENGTH) + { + interface->altsetting = realloc(interface->altsetting, sizeof(struct usb_interface_descriptor) * (interface->num_altsetting + 1)); + if (!interface->altsetting) + { + if (usb_debug >= 1) + fprintf(stderr, "couldn't malloc interface->altsetting\n"); + return -1; + } + + ifp = interface->altsetting + interface->num_altsetting; + interface->num_altsetting++; + + usb_parse_descriptor(buffer, "bbbbbbbbb", ifp); + + /* Skip over the interface */ + buffer += ifp->bLength; + parsed += ifp->bLength; + size -= ifp->bLength; + + begin = buffer; + numskipped = 0; + + /* Skip over any interface, class or vendor descriptors */ + while (size >= DESC_HEADER_LENGTH) + { + usb_parse_descriptor(buffer, "bb", &header); + + if (header.bLength < 2) + { + if (usb_debug >= 1) + fprintf(stderr, "invalid descriptor length of %d\n", header.bLength); + return -1; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == USB_DT_INTERFACE) || + (header.bDescriptorType == USB_DT_ENDPOINT) || + (header.bDescriptorType == USB_DT_CONFIG) || + (header.bDescriptorType == USB_DT_DEVICE)) + break; + + numskipped++; + + buffer += header.bLength; + parsed += header.bLength; + size -= header.bLength; + } + + if (numskipped && usb_debug >= 2) + fprintf(stderr, "skipped %d class/vendor specific interface descriptors\n", numskipped); + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (!len) + { + ifp->extra = NULL; + ifp->extralen = 0; + } + else + { + ifp->extra = malloc(len); + if (!ifp->extra) + { + if (usb_debug >= 1) + fprintf(stderr, "couldn't allocate memory for interface extra descriptors\n"); + ifp->extralen = 0; + return -1; + } + memcpy(ifp->extra, begin, len); + ifp->extralen = len; + } + + /* Did we hit an unexpected descriptor? */ + usb_parse_descriptor(buffer, "bb", &header); + if ((size >= DESC_HEADER_LENGTH) && + ((header.bDescriptorType == USB_DT_CONFIG) || + (header.bDescriptorType == USB_DT_DEVICE))) + return parsed; + + if (ifp->bNumEndpoints > USB_MAXENDPOINTS) + { + if (usb_debug >= 1) + fprintf(stderr, "too many endpoints\n"); + return -1; + } + + if (ifp->bNumEndpoints > 0) + { + ifp->endpoint = (struct usb_endpoint_descriptor *) + malloc(ifp->bNumEndpoints * + sizeof(struct usb_endpoint_descriptor)); + if (!ifp->endpoint) + { + if (usb_debug >= 1) + fprintf(stderr, "couldn't allocate memory for ifp->endpoint\n"); + return -1; + } + + memset(ifp->endpoint, 0, ifp->bNumEndpoints * + sizeof(struct usb_endpoint_descriptor)); + + for (i = 0; i < ifp->bNumEndpoints; i++) + { + usb_parse_descriptor(buffer, "bb", &header); + + if (header.bLength > size) + { + if (usb_debug >= 1) + fprintf(stderr, "ran out of descriptors parsing\n"); + return -1; + } + + retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size); + if (retval < 0) + return retval; + + buffer += retval; + parsed += retval; + size -= retval; + } + } + else + ifp->endpoint = NULL; + + /* We check to see if it's an alternate to this one */ + ifp = (struct usb_interface_descriptor *)buffer; + if (size < USB_DT_INTERFACE_SIZE || + ifp->bDescriptorType != USB_DT_INTERFACE || + !ifp->bAlternateSetting) + return parsed; + } + + return parsed; +} + +int usb_parse_configuration(struct usb_config_descriptor *config, + unsigned char *buffer) +{ + int i, retval, size; + struct usb_descriptor_header header; + + usb_parse_descriptor(buffer, "bbwbbbbb", config); + size = config->wTotalLength; + + if (config->bNumInterfaces > USB_MAXINTERFACES) + { + if (usb_debug >= 1) + fprintf(stderr, "too many interfaces\n"); + return -1; + } + + config->interface = (struct usb_interface *) + malloc(config->bNumInterfaces * + sizeof(struct usb_interface)); + if (!config->interface) + { + if (usb_debug >= 1) + fprintf(stderr, "out of memory\n"); + return -1; + } + + memset(config->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface)); + + buffer += config->bLength; + size -= config->bLength; + + config->extra = NULL; + config->extralen = 0; + + for (i = 0; i < config->bNumInterfaces; i++) + { + int numskipped, len; + unsigned char *begin; + + /* Skip over the rest of the Class Specific or Vendor */ + /* Specific descriptors */ + begin = buffer; + numskipped = 0; + while (size >= DESC_HEADER_LENGTH) + { + usb_parse_descriptor(buffer, "bb", &header); + + if ((header.bLength > size) || (header.bLength < DESC_HEADER_LENGTH)) + { + if (usb_debug >= 1) + fprintf(stderr, "invalid descriptor length of %d\n", header.bLength); + return -1; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == USB_DT_ENDPOINT) || + (header.bDescriptorType == USB_DT_INTERFACE) || + (header.bDescriptorType == USB_DT_CONFIG) || + (header.bDescriptorType == USB_DT_DEVICE)) + break; + + if (usb_debug >= 2) + fprintf(stderr, "skipping descriptor 0x%X\n", header.bDescriptorType); + numskipped++; + + buffer += header.bLength; + size -= header.bLength; + } + + if (numskipped && usb_debug >= 2) + fprintf(stderr, "skipped %d class/vendor specific endpoint descriptors\n", numskipped); + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) + { + /* FIXME: We should realloc and append here */ + if (!config->extralen) + { + config->extra = malloc(len); + if (!config->extra) + { + if (usb_debug >= 1) + fprintf(stderr, "couldn't allocate memory for config extra descriptors\n"); + config->extralen = 0; + return -1; + } + + memcpy(config->extra, begin, len); + config->extralen = len; + } + } + + retval = usb_parse_interface(config->interface + i, buffer, size); + if (retval < 0) + return retval; + + buffer += retval; + size -= retval; + } + + return size; +} + +void usb_destroy_configuration(struct usb_device *dev) +{ + int c, i, j, k; + + if (!dev->config) + return; + + for (c = 0; c < dev->descriptor.bNumConfigurations; c++) + { + struct usb_config_descriptor *cf = &dev->config[c]; + + if (!cf->interface) + continue; + + for (i = 0; i < cf->bNumInterfaces; i++) + { + struct usb_interface *ifp = &cf->interface[i]; + + if (!ifp->altsetting) + continue; + + for (j = 0; j < ifp->num_altsetting; j++) + { + struct usb_interface_descriptor *as = &ifp->altsetting[j]; + + if (as->extra) + free(as->extra); + + if (!as->endpoint) + continue; + + for (k = 0; k < as->bNumEndpoints; k++) + { + if (as->endpoint[k].extra) + free(as->endpoint[k].extra); + } + free(as->endpoint); + } + + free(ifp->altsetting); + } + + free(cf->interface); + } + + free(dev->config); +} + +void usb_fetch_and_parse_descriptors(usb_dev_handle *udev) +{ + struct usb_device *dev = udev->device; + int i; + + if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) + { + if (usb_debug >= 1) + fprintf(stderr, "Too many configurations (%d > %d)\n", dev->descriptor.bNumConfigurations, USB_MAXCONFIG); + return; + } + + if (dev->descriptor.bNumConfigurations < 1) + { + if (usb_debug >= 1) + fprintf(stderr, "Not enough configurations (%d < %d)\n", dev->descriptor.bNumConfigurations, 1); + return; + } + + dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); + if (!dev->config) + { + if (usb_debug >= 1) + fprintf(stderr, "Unable to allocate memory for config descriptor\n"); + return; + } + + memset(dev->config, 0, dev->descriptor.bNumConfigurations * + sizeof(struct usb_config_descriptor)); + + for (i = 0; i < dev->descriptor.bNumConfigurations; i++) + { + unsigned char buffer[USB_DT_CONFIG_SIZE], *bigbuffer; + struct usb_config_descriptor config; + int res; + + /* Get the first 8 bytes so we can figure out what the total length is */ + res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char)i, buffer, USB_DT_CONFIG_SIZE); + if (res < USB_DT_CONFIG_SIZE) + { + if (usb_debug >= 1) + { + if (res < 0) + fprintf(stderr, "Unable to get descriptor (%d)\n", res); + else + fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", USB_DT_CONFIG_SIZE, res); + } + + goto err; + } + + usb_parse_descriptor(buffer, "bbw", &config); + + bigbuffer = malloc(config.wTotalLength); + if (!bigbuffer) + { + if (usb_debug >= 1) + fprintf(stderr, "Unable to allocate memory for descriptors\n"); + goto err; + } + + res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char)i, bigbuffer, + config.wTotalLength); + if (res < config.wTotalLength) + { + if (usb_debug >= 1) + { + if (res < 0) + fprintf(stderr, "Unable to get descriptor (%d)\n", res); + else + fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, res); + } + + free(bigbuffer); + goto err; + } + + res = usb_parse_configuration(&dev->config[i], bigbuffer); + if (usb_debug >= 2) + { + if (res > 0) + fprintf(stderr, "Descriptor data still left\n"); + else if (res < 0) + fprintf(stderr, "Unable to parse descriptors\n"); + } + + free(bigbuffer); + } + + return; + +err: + free(dev->config); + + dev->config = NULL; +} + diff --git a/external/libusb/src/driver_api.h b/external/libusb/src/driver_api.h new file mode 100644 index 00000000..5339a816 --- /dev/null +++ b/external/libusb/src/driver_api.h @@ -0,0 +1,400 @@ +/* libusb-win32, Generic Windows USB Library + * Copyright (c) 2002-2005 Stephan Meyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef __DRIVER_API_H__ +#define __DRIVER_API_H__ + +enum +{ + LIBUSB_DEBUG_OFF, + LIBUSB_DEBUG_ERR, + LIBUSB_DEBUG_WRN, + LIBUSB_DEBUG_MSG, + + LIBUSB_DEBUG_MAX = 0xff, +}; + + +/* 64k */ +#define LIBUSB_MAX_READ_WRITE 0x10000 + +#define LIBUSB_MAX_NUMBER_OF_DEVICES 256 +#define LIBUSB_MAX_NUMBER_OF_CHILDREN 32 + +#define LIBUSB_IOCTL_SET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_CLEAR_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x807, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x808, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x809, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80A, METHOD_IN_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_VENDOR_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_VENDOR_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_RESET_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_ABORT_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x810, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_DEBUG_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x811, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x812, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_ISOCHRONOUS_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x813, METHOD_IN_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_ISOCHRONOUS_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x814, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_CLAIM_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x815, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_RELEASE_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x816, METHOD_BUFFERED, FILE_ANY_ACCESS) + +///////////////////////////////////////////////////////////////////////////// +// supported after 0.1.12.2 +///////////////////////////////////////////////////////////////////////////// + +// [trobinso] adds support for querying device properties +#define LIBUSB_IOCTL_GET_DEVICE_PROPERTY CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x900, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_CUSTOM_REG_PROPERTY CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x901, METHOD_BUFFERED, FILE_ANY_ACCESS) + +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// supported after 1.2.0.0 +///////////////////////////////////////////////////////////////////////////// +#define LIBUSB_IOCTL_GET_CACHED_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x902, METHOD_BUFFERED, FILE_ANY_ACCESS) +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// supported after 1.2.2.0 +///////////////////////////////////////////////////////////////////////////// +#define LIBUSB_IOCTL_GET_OBJECT_NAME CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x8FF, METHOD_BUFFERED, FILE_ANY_ACCESS) +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// supported after 1.2.3.0 +///////////////////////////////////////////////////////////////////////////// +#define LIBUSB_IOCTL_QUERY_DEVICE_INFORMATION CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_PIPE_POLICY CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x906, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_PIPE_POLICY CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x907, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_SET_POWER_POLICY CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x908, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_GET_POWER_POLICY CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x909, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_CONTROL_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_CONTROL_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#define LIBUSB_IOCTL_FLUSH_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90C, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSBK_IOCTL_CLAIM_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90D, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSBK_IOCTL_RELEASE_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90E, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSBK_IOCTL_RELEASE_ALL_INTERFACES CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x90F, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSBK_IOCTL_SET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LIBUSBK_IOCTL_GET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\ + 0x911, METHOD_BUFFERED, FILE_ANY_ACCESS) + +///////////////////////////////////////////////////////////////////////////// +// supported after 1.2.4.8 (libusb0.sys only) +///////////////////////////////////////////////////////////////////////////// +#define LIBUSB_IOCTL_RESET_DEVICE_EX CTL_CODE(FILE_DEVICE_UNKNOWN,\ +0x817, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#include + +enum LIBUSB0_TRANSFER_FLAGS +{ + TRANSFER_FLAGS_SHORT_NOT_OK = 1 << 0, + TRANSFER_FLAGS_ISO_SET_START_FRAME = 1 << 30, + TRANSFER_FLAGS_ISO_ADD_LATENCY = 1 << 31, +}; + +/* +typedef struct +{ + unsigned int timeout; + union + { + struct + { + unsigned int configuration; + } configuration; + struct + { + unsigned int interface; + unsigned int altsetting; + } interface; + struct + { + unsigned int endpoint; + unsigned int packet_size; + + // TODO: max_transfer_size, short transfer not ok, use iso_start_frame + unsigned int max_transfer_size; + unsigned int transfer_flags; + unsigned int iso_start_frame_latency; + } endpoint; + struct + { + unsigned int type; + unsigned int recipient; + unsigned int request; + unsigned int value; + unsigned int index; + } vendor; + struct + { + unsigned int recipient; + unsigned int feature; + unsigned int index; + } feature; + struct + { + unsigned int recipient; + unsigned int index; + unsigned int status; + } status; + struct + { + unsigned int type; + unsigned int index; + unsigned int language_id; + unsigned int recipient; + } descriptor; + struct + { + unsigned int level; + } debug; + struct + { + unsigned int major; + unsigned int minor; + unsigned int micro; + unsigned int nano; + unsigned int mod_value; + } version; + struct + { + unsigned int property; + } device_property; + struct + { + unsigned int key_type; + unsigned int name_offset; + unsigned int value_offset; + unsigned int value_length; + } device_registry_key; + struct + { + // 0 - device plug and play registry key pathname + unsigned int objname_index; + } objname; + }; +} libusb_request; +*/ + +#pragma warning(disable:4201) + +typedef struct +{ + unsigned int interface_number; + unsigned int altsetting_number; + + unsigned char intf_use_index:1; // libusbK Only + unsigned char altf_use_index:1; // libusbK Only + unsigned char:6; + + short interface_index; // libusbK Only + short altsetting_index; // libusbK Only +}interface_request_t; + +typedef struct +{ + unsigned int timeout; + union + { + struct + { + unsigned int configuration; + } configuration; + + interface_request_t intf; + + struct + { + unsigned int endpoint; + unsigned int packet_size; + + // TODO: max_transfer_size, short transfer not ok, use iso_start_frame + unsigned int max_transfer_size; + unsigned int transfer_flags; + unsigned int iso_start_frame_latency; + } endpoint; + struct + { + unsigned int type; + unsigned int recipient; + unsigned int request; + unsigned int value; + unsigned int index; + } vendor; + struct + { + unsigned int recipient; + unsigned int feature; + unsigned int index; + } feature; + struct + { + unsigned int recipient; + unsigned int index; + unsigned int status; + } status; + struct + { + unsigned int type; + unsigned int index; + unsigned int language_id; + unsigned int recipient; + } descriptor; + struct + { + unsigned int level; + } debug; + struct + { + unsigned int major; + unsigned int minor; + unsigned int micro; + unsigned int nano; + unsigned int mod_value; + } version; + struct + { + unsigned int property; + } device_property; + struct + { + unsigned int key_type; + unsigned int name_offset; + unsigned int value_offset; + unsigned int value_length; + } device_registry_key; + struct + { + // 0 - device plug and play registry key pathname + unsigned int objname_index; + } objname; + struct + { + ULONG information_type; + } query_device; + struct + { + unsigned int interface_index; + unsigned int pipe_id; + unsigned int policy_type; + } pipe_policy; + struct + { + unsigned int policy_type; + } power_policy; + struct + { + unsigned int reset_type; + } reset_ex; + + // WDF_USB_CONTROL_SETUP_PACKET control; + struct + { + UCHAR RequestType; + UCHAR Request; + USHORT Value; + USHORT Index; + USHORT Length; + } control; + }; +} libusb_request; +#pragma warning(default:4201) + +#include + +#endif diff --git a/external/libusb/src/error.c b/external/libusb/src/error.c new file mode 100644 index 00000000..d31a4376 --- /dev/null +++ b/external/libusb/src/error.c @@ -0,0 +1,416 @@ +/* Error & Logging functions + + Copyright (C) 2010 Travis Robinson. + website: http://sourceforge.net/projects/libusb-win32 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, please visit www.gnu.org. +*/ + +#include "error.h" +#include +#include +#include + +#if IS_DRIVER + #ifdef __GNUC__ + #define OBJ_KERNEL_HANDLE 0x00000200L + #include + #include + #include + #include "usbdlib_gcc.h" + #else + #include + #endif +#else + #include +#endif + +#define USB_ERROR_BEGIN 500000 + +#ifndef LOG_APPNAME +#define LOG_APPNAME "LOG_APPNAME define missing" +#endif + +#define GetLogLevel(UsbLogLevel) ((UsbLogLevel & LOG_LEVEL_MASK)>LOG_LEVEL_MAX?LOG_LEVEL_MAX:UsbLogLevel & LOG_LEVEL_MASK) +#define GetLogOuput(LogOutputType) (LogOutputType>0?(_LOG_OUTPUT_TYPE & LogOutputType):1) + +void usb_err_v (const char* function, const char* format, va_list args); +void usb_wrn_v (const char* function, const char* format, va_list args); +void usb_msg_v (const char* function, const char* format, va_list args); +void usb_dbg_v (const char* function, const char* format, va_list args); + +void usb_log_v (enum USB_LOG_LEVEL level, const char* function, const char* format, va_list args); +void _usb_log (enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, ...); +void _usb_log_v (enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, va_list args); + +static int usb_log_def_handler(enum USB_LOG_LEVEL level, + const char* app_name, + const char* prefix, + const char* func, + int app_prefix_func_end, + char* message, + int message_length); + +#define STRIP_PREFIX(stringSrc, stringPrefix) \ + (strstr(stringSrc,stringPrefix)==stringSrc?stringSrc+strlen(stringPrefix):stringSrc) + +static const char *log_level_string[LOG_LEVEL_MAX+1] = +{ + "off", + "err", + "wrn", + "", + "dbg", + + "unknown", +}; + +static const char *skipped_function_prefix_list[] = +{ + "usb_registry_", + "usb_", + NULL +}; + +int usb_error_errno = 0; +log_hander_t user_log_hander = NULL; + +#if (defined(_DEBUG) || defined(DEBUG) || defined(DBG)) +int __usb_log_level = LOG_LEVEL_MAX; +#else +int __usb_log_level = LOG_OFF; +#endif + +usb_error_type_t usb_error_type = USB_ERROR_TYPE_NONE; + +const char** skipped_function_prefix = skipped_function_prefix_list; + +#if !IS_DRIVER + +char usb_error_str[LOGBUF_SIZE] = ""; + +char *usb_strerror(void) +{ + switch (usb_error_type) + { + case USB_ERROR_TYPE_NONE: + return "No error"; + case USB_ERROR_TYPE_STRING: + return usb_error_str; + case USB_ERROR_TYPE_ERRNO: + if (usb_error_errno > -USB_ERROR_BEGIN) + return strerror(usb_error_errno); + else + /* Any error we don't know falls under here */ + return "Unknown error"; + } + + return "Unknown error"; +} + +/* returns Windows' last error in a human readable form */ +const char *usb_win_error_to_string(void) +{ + static char tmp[LOGBUF_SIZE]; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_USER_DEFAULT, tmp, sizeof(tmp) - 1, NULL); + + return tmp; +} + + +int usb_win_error_to_errno(void) +{ + switch (GetLastError()) + { + case ERROR_SUCCESS: + return 0; + case ERROR_INVALID_PARAMETER: + return EINVAL; + case ERROR_SEM_TIMEOUT: + case ERROR_OPERATION_ABORTED: + return ETRANSFER_TIMEDOUT; + case ERROR_NOT_ENOUGH_MEMORY: + return ENOMEM; + default: + return EIO; + } +} + +#endif + +void usb_err(const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + usb_err_v(function, format, args); + va_end(args); +} +void usb_wrn(const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + usb_wrn_v(function, format, args); + va_end(args); +} + +void usb_msg(const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + usb_msg_v(function, format, args); + va_end(args); +} + +void usb_dbg(const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + usb_dbg_v(function, format, args); + va_end(args); +} + +void usb_log(enum USB_LOG_LEVEL level, const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + usb_log_v(level, function, format, args); + va_end(args); +} + +void usb_err_v(const char* function, const char* format, va_list args) +{ + usb_log_v(LOG_ERROR, function, format, args); +} + +void usb_wrn_v(const char* function, const char* format, va_list args) +{ + usb_log_v(LOG_WARNING, function, format, args); +} + +void usb_msg_v(const char* function, const char* format, va_list args) +{ + usb_log_v(LOG_INFO, function, format, args); +} + +void usb_dbg_v(const char* function, const char* format, va_list args) +{ + usb_log_v(LOG_DEBUG, function, format, args); +} + +void usb_log_v(enum USB_LOG_LEVEL level, const char* function, const char* format, va_list args) +{ + _usb_log_v(level, LOG_APPNAME, function, format, args); +} + +void _usb_log(enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + _usb_log_v(level, app_name, function, format, args); + va_end(args); +} + +void _usb_log_v(enum USB_LOG_LEVEL level, + const char* app_name, + const char* function, + const char* format, + va_list args) +{ + + char local_buffer[LOGBUF_SIZE]; + int totalCount, count; + const char* prefix; + const char* func; + char* buffer; + int masked_level; + int app_prefix_func_end; +#ifndef LOG_STYLE_SHORT + const char** skip_list = NULL; +#endif + + masked_level = GetLogLevel(level); + + if (__usb_log_level < masked_level && masked_level != LOG_ERROR) return; + buffer = local_buffer; + totalCount = 0; + count = 0; + prefix = log_level_string[masked_level]; + func = function; + app_prefix_func_end = 0; + + if (masked_level > LOG_LEVEL_MAX) masked_level = LOG_LEVEL_MAX; + + if ((level & LOG_RAW) == LOG_RAW) + { + count = _vsnprintf(buffer, LOGBUF_SIZE-1, format, args); + if (count > 0) + { + buffer += count; + totalCount += count; + } + } + else + { +#ifdef LOG_STYLE_SHORT + if ((prefix) && strlen(prefix)) + { + count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s: ", prefix); + } + else + { + count = 0; + } + func = ""; +#else + func = function; + + if (func) + { + // strip some prefixes to shorten function names + skip_list=skipped_function_prefix; + while(*skip_list && ((func)) && func[0]) + { + func = STRIP_PREFIX(func,skip_list[0]); + skip_list++; + } + } + + if(!func) func="none"; + + // print app name, level string and short function name + if ((prefix) && strlen(prefix)) + { + count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s:%s [%s] ", app_name, prefix, func); + } + else + { + count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s:[%s] ", app_name, func); + } +#endif + + if (count >= 0) + { + app_prefix_func_end = count; + buffer += count; + totalCount += count; + count = _vsnprintf(buffer, (LOGBUF_SIZE-1) - totalCount, format, args); + if (count > 0) + { + buffer += count; + totalCount += count; + } + } + } + + if (count < 0) + totalCount = LOGBUF_SIZE - 1; + + // make sure its null terminated + local_buffer[totalCount] = 0; + +#if (!IS_DRIVER) + if (masked_level == LOG_ERROR) + { + // if this is an error message then store it + strncpy(usb_error_str, local_buffer, totalCount); + usb_error_str[totalCount] = '\0'; + usb_error_type = USB_ERROR_TYPE_STRING; + } +#endif + + if (user_log_hander) + { + if (user_log_hander(level, app_name, prefix, func, app_prefix_func_end, local_buffer, totalCount)) + return; + } + if (__usb_log_level >= masked_level) + { + usb_log_def_handler(level, app_name, prefix, func, app_prefix_func_end, local_buffer, totalCount); + } +} + +void usb_log_set_level(enum USB_LOG_LEVEL level) +{ + // Debug builds of the driver force all messages on; all the time; + // Application can no longer change this. + // +#if (defined(_DEBUG) || defined(DEBUG) || defined(DBG)) + __usb_log_level = LOG_LEVEL_MAX; +#else + __usb_log_level = level > LOG_LEVEL_MAX ? LOG_LEVEL_MAX : level; +#endif +} + +int usb_log_get_level() +{ + return __usb_log_level; +} + +/* Default log handler +*/ +static int usb_log_def_handler(enum USB_LOG_LEVEL level, + const char* app_name, + const char* prefix, + const char* func, + int app_prefix_func_end, + char* message, + int message_length) +{ +#if IS_DRIVER + DbgPrint("%s",message); +#else + #if GetLogOuput(LOG_OUTPUT_TYPE_FILE) + FILE* file; + file = fopen(LOG_FILE_PATH,"a"); + if (file) + { + fwrite(message,1,strlen(message),file); + fflush(file); + fclose(file); + } + #endif + + #if GetLogOuput(LOG_OUTPUT_TYPE_STDERR) + fprintf(stderr, "%s", message); + #endif + + #if GetLogOuput(LOG_OUTPUT_TYPE_DEBUGWINDOW) + OutputDebugStringA(message); + #endif + + + #if GetLogOuput(LOG_OUTPUT_TYPE_MSGBOX) + if (GetLogLevel(level)==LOG_ERROR) + { + message[app_prefix_func_end-1]='\0'; + MessageBoxA(NULL,message+strlen(message),message,MB_OK|MB_ICONERROR); + } + #endif + +#endif // IS_DRIVER + + return 1; +} + +void usb_log_set_handler(log_hander_t log_hander) +{ + user_log_hander = log_hander; +} + +log_hander_t usb_log_get_handler(void) +{ + return user_log_hander; +} diff --git a/external/libusb/src/error.h b/external/libusb/src/error.h new file mode 100644 index 00000000..a35ace4e --- /dev/null +++ b/external/libusb/src/error.h @@ -0,0 +1,187 @@ +/* Error & Logging functions + + Copyright (C) 2010 Travis Robinson. + website: http://sourceforge.net/projects/libusb-win32 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU (LGPL) General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU (LGPL) General Public + License for more details. + + You should have received a copy of the GNU (LGPL) General Public License + along with this program; if not, please visit www.gnu.org. +*/ + +#ifndef __ERROR_H__ +#define __ERROR_H__ + +#include + + +enum USB_LOG_LEVEL +{ + LOG_OFF, + LOG_ERROR, + LOG_WARNING, + LOG_INFO, + LOG_DEBUG, + + LOG_LEVEL_MAX, + LOG_LEVEL_MASK=0xff, + LOG_RAW=0x100 + +}; + +/* Connection timed out */ +#define ETRANSFER_TIMEDOUT 116 + +#define LOGBUF_SIZE 512 + +// TARGETTYPEs +#define PROGRAMconsole 0 +#define PROGRAMwindows 1 +#define DYNLINK 2 +#define DRIVER 3 + +// default TARGETTYPE +#ifndef TARGETTYPE +#define TARGETTYPE PROGRAMconsole +#endif + +#define IS_DRIVER (TARGETTYPE==DRIVER) +#define IS_CONSOLE_APP (TARGETTYPE==PROGRAMconsole) +#define IS_WINDOW_APP (TARGETTYPE==PROGRAMwindows) +#define IS_APP (IS_CONSOLE_APP || IS_WINDOW_APP) +#define IS_DLL (TARGETTYPE==DYNLINK) + +// NOTE: LOG_OUTPUT_TYPEs can be combined +// writes log messages to standard error output +#define LOG_OUTPUT_TYPE_STDERR 0x001 + +// writes log messages to Win32 OutputDebugString (DbgPrint for drivers) +#define LOG_OUTPUT_TYPE_DEBUGWINDOW 0x0002 +#define LOG_OUTPUT_TYPE_DBGPRINT 0x0002 + +// displays error log messages to a messagebox (not recommended) +#define LOG_OUTPUT_TYPE_MSGBOX 0x0004 + +// writes log messages to Kernel-mode DbgPrint + +// writes log messages directly to a file +#define LOG_OUTPUT_TYPE_FILE 0x0010 + +// strips all log messages except errors +#define LOG_OUTPUT_TYPE_REMOVE 0x0020 + +#define LOG_OUTPUT_TYPE_DEFAULT 0x0100 + +// File logging is never enabled by default. +// The LOG_OUTPUT_TYPE define must be manually +// set to enable file logging. +#if !IS_DRIVER + #ifndef LOG_DIRECTORY + #define LOG_FILE_PATH LOG_APPNAME ".log" + #else + #define LOG_FILE_PATH LOG_DIRECTORY LOG_APPNAME ".log" + #endif +#endif + +#if (IS_DRIVER) || (IS_DLL) || (IS_WINDOW_APP) + // default logging for drivers and dlls + #define DEF_LOG_OUTPUT_TYPE LOG_OUTPUT_TYPE_DEBUGWINDOW +#else + // default logging for applications and everything else + #define DEF_LOG_OUTPUT_TYPE LOG_OUTPUT_TYPE_STDERR +#endif + +#define _usb_log_do_nothing() while(0) +// Default logging output +#ifdef LOG_OUTPUT_TYPE + // all log messages (except errors) are stripped + #if (LOG_OUTPUT_TYPE & LOG_OUTPUT_TYPE_REMOVE) + #define USBMSG(format,...) _usb_log_do_nothing() + #define USBWRN(format,...) _usb_log_do_nothing() + #define USBDBG(format,...) _usb_log_do_nothing() + #define USBRAWMSG(format,...) _usb_log_do_nothing() + + #define USBMSG0(format) _usb_log_do_nothing() + #define USBWRN0(format) _usb_log_do_nothing() + #define USBDBG0(format) _usb_log_do_nothing() + #define USBRAWMSG0(format) _usb_log_do_nothing() + #endif + + #if (LOG_OUTPUT_TYPE & LOG_OUTPUT_TYPE_DEFAULT) + #define _LOG_OUTPUT_TYPE ((LOG_OUTPUT_TYPE & 0xff)|DEF_LOG_OUTPUT_TYPE) + #else + #define _LOG_OUTPUT_TYPE (LOG_OUTPUT_TYPE) + #endif + +#else + // if the LOG_OUTPUT_TYPE has not been manually set use + // the as defaults. + #define _LOG_OUTPUT_TYPE DEF_LOG_OUTPUT_TYPE +#endif + +// always keep error messages +#define USBERR(format,...) usb_err(__FUNCTION__,format,__VA_ARGS__) +#define USBERR0(format) usb_err(__FUNCTION__,"%s",format) + +// only keep debug log messages in debug builds +#if !(defined(_DEBUG) || defined(DEBUG) || defined(DBG)) && !defined(USBDBG) + #define USBDBG(format,...) _usb_log_do_nothing() + #define USBDBG0(format) _usb_log_do_nothing() +#endif + +// if USBMSG has not been defined as empty (see above) +// then keep all the info and warning log messages +#ifndef USBMSG + #define USBMSG(format,...) usb_msg(__FUNCTION__,format,__VA_ARGS__) + #define USBWRN(format,...) usb_wrn(__FUNCTION__,format,__VA_ARGS__) + #define USBRAWMSG(format,...) usb_log(LOG_INFO|LOG_RAW,__FUNCTION__,format,__VA_ARGS__) + + #define USBMSG0(format) usb_msg(__FUNCTION__,"%s",format) + #define USBWRN0(format) usb_wrn(__FUNCTION__,"%s",format) + #define USBRAWMSG0(format) usb_log(LOG_INFO|LOG_RAW,__FUNCTION__,"%s",format) +#endif + +// if USBDBG has not been defined as empty (see above) +// then keep all the debug log messages +#ifndef USBDBG + #define USBDBG(format,...) usb_dbg(__FUNCTION__,format,__VA_ARGS__) + #define USBDBG0(format) usb_dbg(__FUNCTION__,"%s",format) +#endif + +typedef enum +{ + USB_ERROR_TYPE_NONE = 0, + USB_ERROR_TYPE_STRING, + USB_ERROR_TYPE_ERRNO, +} usb_error_type_t; + +typedef int (*log_hander_t)(enum USB_LOG_LEVEL level, const char*,const char*,const char*, int, char*, int); + +#if (!IS_DRIVER) + const char *usb_win_error_to_string(void); + int usb_win_error_to_errno(void); +#endif + +void usb_log_set_level(enum USB_LOG_LEVEL level); +int usb_log_get_level(void); +void usb_log_set_handler(log_hander_t log_hander); +log_hander_t usb_log_get_handler(void); + +// these are the core logging functions used by the logging macros +// (not used directly) +void usb_err (const char* function, const char* format, ...); +void usb_wrn (const char* function, const char* format, ...); +void usb_msg (const char* function, const char* format, ...); +void usb_dbg (const char* function, const char* format, ...); +void usb_log (enum USB_LOG_LEVEL level, const char* function, const char* format, ...); + +#endif /* _ERROR_H_ */ + diff --git a/external/libusb/src/libusb-win32_version.h b/external/libusb/src/libusb-win32_version.h new file mode 100644 index 00000000..fcb2844a --- /dev/null +++ b/external/libusb/src/libusb-win32_version.h @@ -0,0 +1,18 @@ +/* libusb-win32_version.h ++ auto-generated +*/ +#ifndef __LIBUSB_WIN32_VERSION_H +#define __LIBUSB_WIN32_VERSION_H + +#define __DEFTOSTR(x) #x +#define _DEFTOSTR(x) __DEFTOSTR(x) + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 2 +#define VERSION_MICRO 5 +#define VERSION_NANO 0 +#define VERSION_DATE 07/23/2011 + +#define VERSION VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO.VERSION_NANO +#define RC_VERSION VERSION_MAJOR,VERSION_MINOR,VERSION_MICRO,VERSION_NANO + +#endif diff --git a/external/libusb/src/registry.c b/external/libusb/src/registry.c new file mode 100644 index 00000000..4431efeb --- /dev/null +++ b/external/libusb/src/registry.c @@ -0,0 +1,1651 @@ +/* libusb-win32, Generic Windows USB Library +* Copyright (c) 2002-2005 Stephan Meyer +* Copyright (c) 2010 Travis Robinson +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#if defined(_WIN64) +#include +#else +#include +#endif +#else +#include +#define strlwr(p) _strlwr(p) +#endif + +#include "registry.h" +#include "error.h" + +#define CLASS_KEY_PATH_NT "SYSTEM\\CurrentControlSet\\Control\\Class\\" +#define CLASS_KEY_PATH_9X "SYSTEM\\CurrentControlSet\\Services\\Class\\" + +#define USB_GET_DRIVER_NAME() \ + usb_registry_is_nt() ? driver_name_nt : driver_name_9x; + +#define DISP_CLASS(FilterClass) (strlen(FilterClass->class_name) ? FilterClass->class_name : FilterClass->class_guid) + +static const char *driver_name_nt = "libusb0"; +static const char *driver_name_9x = "libusb0.sys"; + +static const char *default_class_keys_nt[] = +{ + /* USB devices */ + "{36fc9e60-c465-11cf-8056-444553540000}", + /* HID devices */ + "{745a17a0-74d3-11d0-b6fe-00a0c90f57da}", + /* Network devices */ + "{4d36e972-e325-11ce-bfc1-08002be10318}", + /* Image devices */ + "{6bdd1fc6-810f-11d0-bec7-08002be2092f}", + /* Media devices */ + "{4d36e96c-e325-11ce-bfc1-08002be10318}", + /* Modem devices */ + "{4d36e96d-e325-11ce-bfc1-08002be10318}", + /* SmartCardReader devices*/ + "{50dd5230-ba8a-11d1-bf5d-0000f805f530}", + NULL +}; + +static bool_t usb_registry_set_device_state(DWORD state, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data); + +static bool_t usb_registry_get_filter_device_keys(filter_class_t* filter_class, + HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + filter_device_t** found); + +static bool_t usb_registry_get_class_filter_keys(filter_class_t* filter_class, + HKEY reg_class_hkey); + +bool_t usb_registry_is_nt(void) +{ + return GetVersion() < 0x80000000 ? TRUE : FALSE; +} + +bool_t usb_registry_get_property(DWORD which, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char *buf, int size) +{ + DWORD reg_type; + DWORD length = size; + char *p = NULL; + HKEY reg_key = NULL; + + memset(buf, 0, size); + + if (!SetupDiGetDeviceRegistryProperty(dev_info, dev_info_data, which, + ®_type, (BYTE *)buf, size, &length)) + { + return FALSE; + } + + return TRUE; +} + +bool_t usb_registry_mz_to_sz(char* buf_mz, char new_separator) +{ + bool_t success = FALSE; + + while (buf_mz && *buf_mz) + { + success = TRUE; + buf_mz += strlen(buf_mz); + + if (buf_mz[1]) + *buf_mz = new_separator; + + buf_mz++; + } + return success; +} + +bool_t usb_registry_set_property(DWORD which, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char *buf, int size) +{ + char *val_name = NULL; + char *p = NULL; + HKEY reg_key; + DWORD reg_type; + + switch (which) + { + case SPDRP_LOWERFILTERS: + reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ; + val_name = "LowerFilters"; + break; + case SPDRP_UPPERFILTERS: + reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ; + val_name = "UpperFilters"; + break; + default: + return 0; + } + + if (usb_registry_is_nt()) + { + if (size > 2) + { + if (!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data, + which, (BYTE *)buf, size)) + { + USBERR("setting property '%s' failed", val_name); + return FALSE; + } + } + else + { + if (!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data, + which, NULL, 0)) + { + USBERR("deleting property '%s' failed", val_name); + return FALSE; + } + } + } + else + { + p = buf; + + while (*p) + { + if (*p == ',') + { + *p = 0; + } + p += (strlen(p) + 1); + } + + reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data, + DICS_FLAG_GLOBAL, + 0, DIREG_DEV, KEY_ALL_ACCESS); + + if (reg_key == INVALID_HANDLE_VALUE) + { + USBERR0("reading registry key failed\n"); + return FALSE; + } + + if (size > 3) + { + if (RegSetValueEx(reg_key, val_name, 0, reg_type, (BYTE *)buf, + size) != ERROR_SUCCESS) + { + USBERR("setting property '%s' failed", val_name); + RegCloseKey(reg_key); + return FALSE; + } + } + else + { + if (RegDeleteValue(reg_key, val_name) != ERROR_SUCCESS) + { + USBERR("deleting property '%s' failed", val_name); + RegCloseKey(reg_key); + return FALSE; + } + } + RegCloseKey(reg_key); + } + + return TRUE; +} + +bool_t usb_registry_insert_class_filter(filter_context_t* filter_context) +{ + const char *driver_name; + filter_class_t *key; + char buf[MAX_PATH]; + + driver_name = USB_GET_DRIVER_NAME(); + + if (!filter_context->class_filters) + { + return TRUE; + } + + key = filter_context->class_filters; + + while (key) + { + if (usb_registry_get_mz_value(key->name, "UpperFilters", + buf, sizeof(buf))) + { + if (usb_registry_mz_string_find(buf, driver_name, TRUE)) + { + key = key->next; + continue; + } + } + + USBMSG("inserting class filter %s..\n", DISP_CLASS(key)); + + + usb_registry_mz_string_insert(buf, driver_name); + + if (!usb_registry_set_mz_value(key->name, "UpperFilters", buf, + usb_registry_mz_string_size(buf))) + { + USBERR0("unable to set registry value\n"); + } + else + { + key->action = FT_CLASS_UPPERFILTER; + filter_context->class_filters_modified = TRUE; + } + + key = key->next; + } + + return TRUE; +} + +bool_t usb_registry_remove_class_filter(filter_context_t* filter_context) +{ + const char *driver_name; + filter_class_t *key; + char buf[MAX_PATH]; + + driver_name = USB_GET_DRIVER_NAME(); + + if (!filter_context->class_filters) + { + return TRUE; + } + + key = filter_context->class_filters; + + while (key) + { + if (usb_registry_get_mz_value(key->name, "UpperFilters", + buf, sizeof(buf))) + { + if (usb_registry_mz_string_find(buf, driver_name, TRUE)) + { + key->action = FT_CLASS_UPPERFILTER; + filter_context->class_filters_modified = TRUE; + + USBMSG("removing class filter %s..\n", DISP_CLASS(key)); + usb_registry_mz_string_remove(buf, driver_name, TRUE); + + if (!usb_registry_set_mz_value(key->name, "UpperFilters", buf, usb_registry_mz_string_size(buf))) + { + USBERR("failed removing class filter %s..\n", DISP_CLASS(key)); + } + else + { + key->action = FT_CLASS_UPPERFILTER; + filter_context->class_filters_modified = TRUE; + } + } + } + + key = key->next; + } + + return TRUE; +} + +bool_t usb_registry_remove_device_filter(filter_context_t* filter_context) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index = 0; + char filters[MAX_PATH]; + char hwid[MAX_PATH]; + const char *driver_name; + bool_t remove_device_filters; + + driver_name = USB_GET_DRIVER_NAME(); + + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + dev_index = 0; + + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return FALSE; + } + + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (usb_registry_get_hardware_id(dev_info, &dev_info_data, hwid)) + { + if (filter_context->remove_all_device_filters) + { + // remove all device upper/lower filters. + remove_device_filters = TRUE; + } + else if (usb_registry_match_filter_device(&filter_context->device_filters, dev_info, &dev_info_data)) + { + // if not, remove only the ones specified by the user. + remove_device_filters = TRUE; + } + else + { + // skip device filter removal for this device. + remove_device_filters = FALSE; + } + + if (remove_device_filters) + { + /* remove libusb as a device upper filter */ + if (usb_registry_get_property(SPDRP_UPPERFILTERS, dev_info, + &dev_info_data, + filters, sizeof(filters))) + { + if (usb_registry_mz_string_find(filters, driver_name, TRUE)) + { + int size; + USBMSG("removing device upper filter %s..\n", hwid+4); + + usb_registry_mz_string_remove(filters, driver_name, TRUE); + size = usb_registry_mz_string_size(filters); + + usb_registry_set_property(SPDRP_UPPERFILTERS, dev_info, + &dev_info_data, filters, size); + + if (!filter_context->class_filters) + { + USBMSG("restarting device %s..\n", hwid+4); + usb_registry_restart_device(dev_info, &dev_info_data); + } + } + } + + /* remove libusb as a device lower filter */ + if (usb_registry_get_property(SPDRP_LOWERFILTERS, dev_info, + &dev_info_data, + filters, sizeof(filters))) + { + if (usb_registry_mz_string_find(filters, driver_name, TRUE)) + { + int size; + USBMSG("removing device lower filter %s..\n", hwid+4); + usb_registry_mz_string_remove(filters, driver_name, TRUE); + size = usb_registry_mz_string_size(filters); + + usb_registry_set_property(SPDRP_LOWERFILTERS, dev_info, + &dev_info_data, filters, size); + + if (!filter_context->class_filters) + { + USBMSG("restarting device %s..\n", hwid+4); + usb_registry_restart_device(dev_info, &dev_info_data); + } + } + } + } + } + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); + + return TRUE; +} + +bool_t usb_registry_fill_filter_hwid(const char* hwid, filter_hwid_t* filter_hwid) +{ + const char* hwid_part; + + if ((hwid_part = strstr(hwid, "vid_"))) + sscanf(hwid_part,"vid_%04x",&filter_hwid->vid); + else + filter_hwid->vid = -1; + + if ((hwid_part = strstr(hwid, "pid_"))) + sscanf(hwid_part,"pid_%04x",&filter_hwid->pid); + else + filter_hwid->pid = -1; + + if ((hwid_part = strstr(hwid, "mi_"))) + sscanf(hwid_part,"mi_%02x",&filter_hwid->mi); + else + filter_hwid->mi = -1; + + if ((hwid_part = strstr(hwid, "rev_"))) + sscanf(hwid_part,"rev_%04u",&filter_hwid->rev); + else + filter_hwid->rev = -1; + + return (filter_hwid->vid != -1 && filter_hwid->pid != -1); +} + +filter_device_t* usb_registry_match_filter_device(filter_device_t** head, + HDEVINFO dev_info, PSP_DEVINFO_DATA dev_info_data) +{ + filter_device_t* p = *head; + char devid[MAX_PATH]; + char hwid[MAX_PATH]; + char hwid_find[MAX_PATH]; + filter_hwid_t find_hwid; + filter_hwid_t search_hwid; + + if (CM_Get_Device_ID(dev_info_data->DevInst, devid, sizeof(devid), 0) != CR_SUCCESS) + { + USBERR0("failed getting device id\n"); + return NULL; + } + + if (!usb_registry_get_hardware_id(dev_info, dev_info_data, hwid)) + { + USBERR0("failed getting device id\n"); + return NULL; + } + + _strlwr(hwid); + if (!usb_registry_fill_filter_hwid(hwid, &find_hwid)) + return NULL; + + while(p) + { + if (strlen(p->device_id)) + { + // matching on device instance id + if (_stricmp(devid, p->device_id) == 0) + { + // found a match + return p; + } + } + else + { + // matching on id parts + strcpy(hwid_find, p->device_hwid); + _strlwr(hwid_find); + if (usb_registry_fill_filter_hwid(hwid_find, &search_hwid)) + { + if (find_hwid.vid == search_hwid.vid && + find_hwid.pid == search_hwid.pid && + ((search_hwid.mi == -1) || (find_hwid.mi == search_hwid.mi)) && + ((search_hwid.rev == -1) || (find_hwid.rev == search_hwid.rev))) + { + return p; + } + } + } + p = p->next; + } + + return NULL; +} + +bool_t usb_registry_remove_device_regvalue(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data, const char* key_name) +{ + HKEY reg_key; + reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS); + if (reg_key) + { + if (RegDeleteValueA(reg_key, key_name) == ERROR_SUCCESS) + { + USBMSG("removed %s from device registry..\n", key_name); + RegCloseKey(reg_key); + return TRUE; + } + RegCloseKey(reg_key); + } + return FALSE; +} + +bool_t usb_registry_insert_device_filter(filter_context_t* filter_context, char* hwid, bool_t upper, + HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data) +{ + + const char *driver_name; + DWORD spdrp_filters; + char filters[MAX_PATH]; + int size; + + driver_name = USB_GET_DRIVER_NAME(); + spdrp_filters = upper ? SPDRP_UPPERFILTERS : SPDRP_LOWERFILTERS; + + if (usb_registry_get_property(spdrp_filters, dev_info, dev_info_data, filters, sizeof(filters))) + { + if (usb_registry_mz_string_find(filters, driver_name, TRUE)) + { + if (usb_registry_remove_device_regvalue(dev_info, dev_info_data, "SurpriseRemovalOK")) + { + if (!filter_context->class_filters) + { + USBMSG("restarting device %s..\n", hwid+4); + usb_registry_restart_device(dev_info, dev_info_data); + } + } + return TRUE; + } + } + USBMSG("inserting device %s filter %s..\n", + upper ? "upper" : "lower", hwid+4); + + if(usb_registry_mz_string_insert(filters, driver_name)) + { + size = usb_registry_mz_string_size(filters); + if (usb_registry_set_property(spdrp_filters, dev_info, dev_info_data, filters, size)) + { + usb_registry_remove_device_regvalue(dev_info, dev_info_data, "SurpriseRemovalOK"); + + if (!filter_context->class_filters) + { + USBMSG("restarting device %s..\n", hwid+4); + usb_registry_restart_device(dev_info, dev_info_data); + } + return TRUE; + } + } + + return FALSE; +} + +bool_t usb_registry_insert_device_filters(filter_context_t* filter_context) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index = 0; + char hwid[MAX_PATH]; + const char *driver_name; + filter_device_t* found; + bool_t is_libusb_service; + + if (!filter_context->device_filters) + return TRUE; + + driver_name = USB_GET_DRIVER_NAME(); + + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + dev_index = 0; + + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return FALSE; + } + + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (usb_registry_is_service_or_filter_libusb(dev_info, &dev_info_data, &is_libusb_service)) + { + if (!is_libusb_service) + { + if (usb_registry_get_property(SPDRP_HARDWAREID, dev_info, &dev_info_data, hwid, MAX_PATH)) + { + if ((found=usb_registry_match_filter_device(&filter_context->device_filters, dev_info, &dev_info_data))) + { + if (!usb_registry_get_property(SPDRP_DEVICEDESC, dev_info, + &dev_info_data, + found->device_name, sizeof(found->device_name))) + { + USBWRN0("unable to get SPDRP_DEVICEDESC\n"); + } + if (!usb_registry_get_property(SPDRP_MFG, dev_info, + &dev_info_data, + found->device_mfg, sizeof(found->device_mfg))) + { + USBWRN0("unable to get SPDRP_MFG\n"); + } + + if (found->action & FT_DEVICE_UPPERFILTER) + { + if (!usb_registry_insert_device_filter(filter_context, hwid, TRUE, dev_info, &dev_info_data)) + { + USBERR("failed adding upper device filter for %s\n",found->device_hwid); + } + } + if (found->action & FT_DEVICE_LOWERFILTER) + { + if (!usb_registry_insert_device_filter(filter_context, hwid, FALSE, dev_info, &dev_info_data)) + { + USBERR("failed adding lower device filter for %s\n",found->device_hwid); + } + } + } + } + } + } + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); + + return TRUE; +} +static bool_t usb_registry_set_device_state(DWORD state, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data) +{ + SP_PROPCHANGE_PARAMS prop_params; + + memset(&prop_params, 0, sizeof(SP_PROPCHANGE_PARAMS)); + + prop_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); + prop_params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; + prop_params.StateChange = state; + prop_params.Scope = DICS_FLAG_CONFIGSPECIFIC;//DICS_FLAG_GLOBAL; + prop_params.HwProfile = 0; + + + if (!SetupDiSetClassInstallParams(dev_info, dev_info_data, + (SP_CLASSINSTALL_HEADER *)&prop_params, + sizeof(SP_PROPCHANGE_PARAMS))) + { + USBERR0("setting class install parameters failed\n"); + return FALSE; + } + + + if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, dev_info, dev_info_data)) + { + USBERR0("calling class installer failed\n"); + return FALSE; + } + + return TRUE; +} + +bool_t usb_registry_restart_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data) +{ + return usb_registry_set_device_state(DICS_PROPCHANGE, dev_info, + dev_info_data); +} + +bool_t usb_registry_stop_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data) +{ + return usb_registry_set_device_state(DICS_DISABLE, dev_info, + dev_info_data); +} + +bool_t usb_registry_start_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data) +{ + return usb_registry_set_device_state(DICS_ENABLE, dev_info, + dev_info_data); +} + +bool_t usb_registry_get_device_filter_type(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + filter_type_e* filter_type) +{ + char filters[MAX_PATH]; + const char* driver_name; + + *filter_type = FT_NONE; + driver_name = USB_GET_DRIVER_NAME(); + + if (usb_registry_get_property(SPDRP_UPPERFILTERS, dev_info, + dev_info_data, + filters, sizeof(filters))) + { + if (usb_registry_mz_string_find(filters, driver_name, TRUE)) + { + *filter_type |= FT_DEVICE_UPPERFILTER; + } + } + + if (usb_registry_get_property(SPDRP_LOWERFILTERS, dev_info, + dev_info_data, + filters, sizeof(filters))) + { + if (usb_registry_mz_string_find(filters, driver_name, TRUE)) + { + *filter_type |= FT_DEVICE_LOWERFILTER; + } + } + + return TRUE; +} + +bool_t usb_registry_is_service_libusb(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + bool_t* is_libusb_service) +{ + char service_name[MAX_PATH]; + const char* driver_name; + + driver_name = USB_GET_DRIVER_NAME(); + *is_libusb_service = FALSE; + if (!usb_registry_get_property(SPDRP_SERVICE, dev_info, dev_info_data, + service_name, sizeof(service_name))) + { + return FALSE; + } + + if (_stricmp(service_name, driver_name)==0) + { + *is_libusb_service = TRUE; + } + + return TRUE; +} + +bool_t usb_registry_is_service_or_filter_libusb(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + bool_t* is_libusb_service) +{ + char service_name[MAX_PATH]; + const char* driver_name; + filter_type_e filter_type; + + driver_name = USB_GET_DRIVER_NAME(); + *is_libusb_service = FALSE; + if (!usb_registry_get_property(SPDRP_SERVICE, dev_info, dev_info_data, + service_name, sizeof(service_name))) + { + return FALSE; + } + + if (_stricmp(service_name, driver_name)==0) + { + *is_libusb_service = TRUE; + } + else if ((usb_registry_get_device_filter_type(dev_info, dev_info_data, &filter_type)) && filter_type != FT_NONE) + { + *is_libusb_service = TRUE; + } + + return TRUE; +} + +void usb_registry_stop_libusb_devices(void) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index = 0; + bool_t is_libusb_service; + + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + dev_index = 0; + + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, + DIGCF_ALLCLASSES | DIGCF_PRESENT); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return; + } + + USBMSG0("stopping devices..\n"); + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (usb_registry_is_service_libusb(dev_info, &dev_info_data, &is_libusb_service)) + { + if (is_libusb_service) + { + usb_registry_stop_device(dev_info, &dev_info_data); + } + } + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); +} + +void usb_registry_start_libusb_devices(void) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index = 0; + bool_t is_libusb_service; + + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + dev_index = 0; + + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, + DIGCF_ALLCLASSES | DIGCF_PRESENT); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return; + } + + USBMSG0("starting devices..\n"); + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (usb_registry_is_service_libusb(dev_info, &dev_info_data, &is_libusb_service)) + { + if (is_libusb_service) + { + usb_registry_start_device(dev_info, &dev_info_data); + } + } + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); +} + +bool_t usb_registry_get_hardware_id(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char* max_path_buffer) +{ + if (!usb_registry_get_property(SPDRP_HARDWAREID, dev_info, dev_info_data, + max_path_buffer, MAX_PATH-1)) + { + USBWRN0("failed\n"); + return FALSE; + } + max_path_buffer[MAX_PATH-1]='\0'; + return TRUE; +} + +bool_t usb_registry_get_mz_value(const char *key, const char *value, + char *buf, int size) +{ + HKEY reg_key = NULL; + DWORD reg_type; + DWORD reg_length = size; + bool_t ret = FALSE; + char *p; + + memset(buf, 0, size); + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, ®_key) + == ERROR_SUCCESS) + { + if (RegQueryValueEx(reg_key, value, NULL, ®_type, + buf, ®_length) == ERROR_SUCCESS) + { + if (reg_type == REG_SZ) + { + p = buf; + while (*p) + { + if (*p == ',') + { + *p = 0; + } + p++; + } + } + + ret = TRUE; + } + } + + if (reg_key) + { + RegCloseKey(reg_key); + } + + return ret; +} + + +bool_t usb_registry_set_mz_value(const char *key, const char *value, + char *buf, int size) +{ + HKEY reg_key = NULL; + bool_t ret = FALSE; + char *p; + + /* convert REG_MULTI_SZ to REG_SZ */ + if (!usb_registry_is_nt()) + { + p = buf; + + while (*p && *(p + 1)) + { + if (*p == 0) + { + *p = ','; + } + p++; + } + } + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, ®_key) + == ERROR_SUCCESS) + { + if (size > 2) + { + if (usb_registry_is_nt()) + { + if (RegSetValueEx(reg_key, value, 0, REG_MULTI_SZ, buf, size) + == ERROR_SUCCESS) + { + ret = TRUE; + } + } + else + { + if (RegSetValueEx(reg_key, value, 0, REG_SZ, buf, size) + == ERROR_SUCCESS) + { + ret = TRUE; + } + } + } + else + { + if (RegDeleteValue(reg_key, value) == ERROR_SUCCESS) + { + ret = TRUE; + } + } + } + + if (reg_key) + { + RegCloseKey(reg_key); + } + + return ret; +} + +int usb_registry_mz_string_size(const char *src) +{ + char *p = (char *)src; + + if (!src) + { + return 0; + } + + while (*p) + { + p += (strlen(p) + 1); + } + + return (int)(p - src) + 1; +} + +char *usb_registry_mz_string_find_sub(const char *src, const char *str) +{ + while (*src) + { + if (strstr(src, str)) + { + return (char *)src; + } + src += (strlen(src) + 1); + } + + return NULL; +} + +char *usb_registry_mz_string_find(const char *src, const char *str, bool_t no_case) +{ + int ret; + while (*src) + { + if (no_case) + { + ret = _stricmp(src, str); + } + else + { + ret = strcmp(src, str); + } + if (!ret) + { + return (char *)src; + } + src += strlen(src) + 1; + } + + return NULL; +} + +bool_t usb_registry_mz_string_insert(char *src, const char *str) +{ + while (*src) + { + src += (strlen(src) + 1); + } + + memcpy(src, str, strlen(str)); + + src += strlen(str); + + *src = 0; + *(src + 1) = 0; + + return TRUE; +} + +bool_t usb_registry_mz_string_remove(char *src, const char *str, bool_t no_case) +{ + char *p; + bool_t ret = FALSE; + int size; + + do + { + src = usb_registry_mz_string_find(src, str, no_case); + + if (!src) + { + break; + } + else + { + ret = TRUE; + } + + p = src; + size = 0; + + while (*p) + { + p += strlen(p) + 1; + size += (long)(strlen(p) + 1); + } + + memmove(src, src + strlen(src) + 1, size); + + } + while (1); + + return TRUE; +} + +void usb_registry_mz_string_lower(char *src) +{ + while (*src) + { + strlwr(src); + src += (strlen(src) + 1); + } +} + +bool_t usb_registry_restart_all_devices(void) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index; + char id[MAX_PATH]; + int hub_index = 0; + + dev_index = 0; + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, + DIGCF_ALLCLASSES | DIGCF_PRESENT); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return FALSE; + } + + USBMSG0("restarting devices..\n"); + + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (!usb_registry_get_hardware_id(dev_info, &dev_info_data, id)) + { + dev_index++; + continue; + } + usb_registry_mz_string_lower(id); + + /* restart root hubs */ + if (usb_registry_mz_string_find_sub(id, "root_hub")) + { + USBMSG("restarting root hub #%d..\n",++hub_index); + usb_registry_restart_device(dev_info, &dev_info_data); + } + + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); + + return TRUE; +} + +bool_t usb_registry_add_filter_device_keys(filter_device_t** head, + const char* id, + const char* hwid, + const char* name, + const char* mfg, + const char* uppers_mz, + const char* lowers_mz, + filter_device_t** found) +{ + filter_device_t *p = *head; + *found = NULL; + + while (p) + { + if (strlen(id)) + { + if (_stricmp(p->device_id, id)==0) + { + *found = p; + break; + } + } + p = p->next; + } + + if (!(*found)) + { + p = malloc(sizeof(filter_device_t)); + if (!p) + return FALSE; + + memset(p, 0, sizeof(filter_device_t)); + + *found = p; + p->next = *head; + *head = p; + } + + strcpy(p->device_id, id); + strcpy(p->device_hwid, hwid); + + if (strlen(name)) + strcpy(p->device_name, name); + + if (strlen(mfg)) + strcpy(p->device_mfg, mfg); + + if (strlen(uppers_mz)) + memcpy(p->device_uppers, uppers_mz, (size_t)usb_registry_mz_string_size(uppers_mz)); + + if (strlen(lowers_mz)) + memcpy(p->device_lowers, lowers_mz, (size_t)usb_registry_mz_string_size(lowers_mz)); + + return TRUE; +} + +bool_t usb_registry_add_filter_file_keys(filter_file_t** head, + const char* name, + filter_file_t** found) +{ + filter_file_t *p = *head; + *found = NULL; + + while (p) + { + if (_stricmp(p->name, name)==0) + { + *found = p; + return TRUE; + } + p = p->next; + } + + p = malloc(sizeof(filter_file_t)); + + if (!p) + return FALSE; + + memset(p, 0, sizeof(filter_file_t)); + + strcpy(p->name, name); + + *found = p; + p->next = *head; + *head = p; + + return TRUE; +} + +static bool_t usb_registry_get_filter_device_keys(filter_class_t* filter_class, + HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + filter_device_t** found) +{ + + char id[MAX_PATH]; + char hwid[MAX_PATH]; + char name[MAX_PATH]; + char mfg[MAX_PATH]; + char lowers_mz[MAX_PATH]; + char uppers_mz[MAX_PATH]; + + *found = NULL; + if (dev_info && filter_class) + { + if (CM_Get_Device_ID(dev_info_data->DevInst, id, sizeof(id), 0) != CR_SUCCESS) + { + USBWRN0("unable to get device instance id\n"); + return FALSE; + } + + if (!usb_registry_get_property(SPDRP_HARDWAREID, dev_info, + dev_info_data, + hwid, sizeof(hwid))) + { + USBWRN0("unable to get SPDRP_HARDWAREID\n"); + return FALSE; + } + + if (!usb_registry_get_property(SPDRP_DEVICEDESC, dev_info, + dev_info_data, + name, sizeof(name))) + { + USBWRN0("unable to get SPDRP_DEVICEDESC\n"); + } + if (!usb_registry_get_property(SPDRP_MFG, dev_info, + dev_info_data, + mfg, sizeof(mfg))) + { + USBWRN0("unable to get SPDRP_MFG\n"); + } + + usb_registry_get_property(SPDRP_UPPERFILTERS, dev_info, dev_info_data, uppers_mz, sizeof(uppers_mz)); + usb_registry_get_property(SPDRP_LOWERFILTERS, dev_info, dev_info_data, lowers_mz, sizeof(lowers_mz)); + + return usb_registry_add_filter_device_keys(&filter_class->class_filter_devices, + id, hwid, name, mfg, uppers_mz, lowers_mz, found); + } + + return FALSE; +} +bool_t usb_registry_add_usb_class_key(filter_context_t* filter_context, const char* class_guid) +{ + char tmp[MAX_PATH]; + const char *class_path = CLASS_KEY_PATH_NT; + filter_class_t* found = NULL; + + if ((strlen(class_path) + strlen(class_guid)) < sizeof(tmp)) + { + sprintf(tmp, "%s%s", class_path, class_guid); + return usb_registry_add_class_key(&filter_context->class_filters, tmp, "", class_guid, &found, FALSE); + } + return FALSE; +} + +bool_t usb_registry_get_usb_class_keys(filter_context_t* filter_context, bool_t refresh_only) +{ + HDEVINFO dev_info; + SP_DEVINFO_DATA dev_info_data; + int dev_index = 0; + int i; + char class[MAX_PATH]; + char class_name[MAX_PATH]; + char tmp[MAX_PATH]; + DWORD class_property; + const char *class_path; + const char **default_class_keys; + filter_class_t* found = NULL; + filter_device_t* found_device = NULL; + bool_t is_libusb_service; + bool_t add_device_classes = FALSE; + bool_t success; + + class_property = SPDRP_CLASSGUID; + class_path = CLASS_KEY_PATH_NT; + default_class_keys = default_class_keys_nt; + i = 0; + + if (filter_context->switches.add_default_classes) + { + while (default_class_keys[i]) + { + if ((strlen(class_path) + strlen(default_class_keys[i])) < sizeof(tmp)) + { + sprintf(tmp, "%s%s", class_path, default_class_keys[i]); + usb_registry_add_class_key(&filter_context->class_filters, tmp, "", default_class_keys[i], &found, FALSE); + } + i++; + } + } + if (filter_context->filter_mode == FM_INSTALL) + add_device_classes = filter_context->switches.add_device_classes | filter_context->switches.add_all_classes; + else if (filter_context->filter_mode == FM_LIST) + add_device_classes = filter_context->switches.add_device_classes; + else if (filter_context->filter_mode == FM_REMOVE) + return TRUE; + + if (add_device_classes || refresh_only) + { + dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); + dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, + DIGCF_ALLCLASSES); + + if (dev_info == INVALID_HANDLE_VALUE) + { + USBERR0("getting device info set failed\n"); + return FALSE; + } + + while (SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) + { + if (filter_context->filter_mode == FM_INSTALL) + success = usb_registry_is_service_or_filter_libusb(dev_info, &dev_info_data, &is_libusb_service); + else + success = usb_registry_is_service_libusb(dev_info, &dev_info_data, &is_libusb_service); + + if (success) + { + if (!is_libusb_service) + { + if (!usb_registry_get_property(SPDRP_CLASSGUID, dev_info, &dev_info_data, class, sizeof(class))) + { + dev_index++; + continue; + } + + strlwr(class); + + usb_registry_get_property(SPDRP_CLASS, dev_info, &dev_info_data, class_name, sizeof(class_name)); + + if ((strlen(class_path) + strlen(class)) < sizeof(tmp)) + { + sprintf(tmp, "%s%s", class_path, class); + usb_registry_add_class_key(&filter_context->class_filters, tmp, class_name, class, &found, + (add_device_classes) ? FALSE : refresh_only); + + if (found) + { + usb_registry_get_filter_device_keys(found, dev_info, &dev_info_data, &found_device); + } + } + } + } + + dev_index++; + } + + SetupDiDestroyDeviceInfoList(dev_info); + } + + return TRUE; +} + +bool_t usb_registry_get_all_class_keys(filter_context_t* filter_context, bool_t refresh_only) +{ + const char *class_path; + HKEY reg_key, reg_class_key; + char class[MAX_PATH]; + char class_name[MAX_PATH]; + char tmp[MAX_PATH]; + filter_class_t* found = NULL; + DWORD reg_type; + bool_t add_all_classes = FALSE; + + switch(filter_context->filter_mode) + { + case FM_INSTALL: + add_all_classes = FALSE; + break; + case FM_REMOVE: + if (!refresh_only && (filter_context->switches.add_all_classes || filter_context->switches.add_device_classes)) + { + add_all_classes = TRUE; + } + break; + case FM_LIST: + add_all_classes = filter_context->switches.add_all_classes; + break; + } + + if (add_all_classes || refresh_only) + { + if (usb_registry_is_nt()) + { + class_path = CLASS_KEY_PATH_NT; + } + else + { + class_path = CLASS_KEY_PATH_9X; + } + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, class_path, 0, KEY_ALL_ACCESS, ®_key) == ERROR_SUCCESS) + { + DWORD i = 0; + DWORD size = sizeof(class); + FILETIME junk; + + memset(class, 0, sizeof(class)); + + while (RegEnumKeyEx(reg_key, i, class, &size, 0, NULL, NULL, &junk) == ERROR_SUCCESS) + { + strlwr(class); + + if ((strlen(class_path) + strlen(class)) < sizeof(tmp)) + { + memset(class_name,0,sizeof(class_name)); + sprintf(tmp, "%s%s", class_path, class); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, tmp, 0, KEY_ALL_ACCESS, ®_class_key) == ERROR_SUCCESS) + { + size = sizeof(class_name); + RegQueryValueExA(reg_class_key, "Class", NULL, ®_type, class_name, &size); + + usb_registry_add_class_key(&filter_context->class_filters, tmp, class_name, class, &found, + (add_all_classes) ? FALSE : refresh_only); + + if (found) + { + usb_registry_get_class_filter_keys(found, reg_class_key); + } + RegCloseKey(reg_class_key); + } + } + + memset(class, 0, sizeof(class)); + size = sizeof(class); + i++; + } + + RegCloseKey(reg_key); + } + } + return TRUE; +} + +bool_t usb_registry_lookup_class_keys_by_name(filter_class_t** head) +{ + const char *class_path; + HKEY reg_key, reg_class_key; + char class[MAX_PATH]; + char class_name[MAX_PATH]; + char tmp[MAX_PATH]; + filter_class_t* found = NULL; + DWORD reg_type; + + if (usb_registry_is_nt()) + { + class_path = CLASS_KEY_PATH_NT; + } + else + { + class_path = CLASS_KEY_PATH_9X; + } + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, class_path, 0, KEY_ALL_ACCESS, + ®_key) == ERROR_SUCCESS) + { + DWORD i = 0; + DWORD size = sizeof(class); + FILETIME junk; + + memset(class, 0, sizeof(class)); + + while (RegEnumKeyEx(reg_key, i, class, &size, 0, NULL, NULL, &junk) == ERROR_SUCCESS) + { + strlwr(class); + + if ((strlen(class_path) + strlen(class)) < sizeof(tmp)) + { + memset(class_name,0,sizeof(class_name)); + sprintf(tmp, "%s%s", class_path, class); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, tmp, 0, KEY_ALL_ACCESS, ®_class_key) == ERROR_SUCCESS) + { + size = sizeof(class_name); + RegQueryValueExA(reg_class_key, "Class", NULL, ®_type, class_name, &size); + RegCloseKey(reg_class_key); + + usb_registry_add_class_key(head, tmp, class_name, class, &found, TRUE); + } + } + + memset(class, 0, sizeof(class)); + size = sizeof(class); + i++; + } + + RegCloseKey(reg_key); + } + + return TRUE; +} + +bool_t usb_registry_add_class_key(filter_class_t **head, + const char *key, + const char *class_name, + const char *class_guid, + filter_class_t **found, + bool_t update_only) +{ + filter_class_t *p = *head; + *found = NULL; + if (key) + { + + if (strlen(key) >= MAX_PATH) + return FALSE; + + while (p) + { + if (!strlen(p->name)) + { + if (!_stricmp(p->class_name, class_name)) + { + *found = p; + } + } + else + { + if (!_stricmp(p->name, key)) + { + *found = p; + } + } + if (*found) + { + strcpy(p->name, key); + strcpy(p->class_guid, class_guid); + strcpy(p->class_name, class_name); + + return TRUE; + } + p = p->next; + } + + if (update_only) + return TRUE; + + p = malloc(sizeof(filter_class_t)); + + if (!p) + return FALSE; + + memset(p, 0, sizeof(filter_class_t)); + strcpy(p->name, key); + strcpy(p->class_guid, class_guid); + strcpy(p->class_name, class_name); + + *found = p; + p->next = *head; + *head = p; + + return TRUE; + } + + return FALSE; +} + +bool_t usb_registry_free_class_keys(filter_class_t **head) +{ + filter_class_t *p = *head; + filter_class_t *q; + + while (p) + { + q = p->next; + usb_registry_free_filter_devices(&p->class_filter_devices); + free(p); + p = q; + } + + *head = NULL; + + return TRUE; +} + +bool_t usb_registry_free_filter_files(filter_file_t **head) +{ + filter_file_t *p = *head; + filter_file_t *q; + + while (p) + { + q = p->next; + free(p); + p = q; + } + + *head = NULL; + + return TRUE; +} + +bool_t usb_registry_free_filter_devices(filter_device_t **head) +{ + filter_device_t *p = *head; + filter_device_t *q; + + while (p) + { + q = p->next; + free(p); + p = q; + } + + *head = NULL; + + return TRUE; +} + +static bool_t usb_registry_get_class_filter_keys(filter_class_t* filter_class, HKEY reg_class_hkey) +{ + DWORD reg_type; + DWORD size; + + // Get the class filters. A non-existent key means no filters + size = sizeof(filter_class->class_uppers) - 1; + if (RegQueryValueExA(reg_class_hkey, "UpperFilters", NULL, ®_type, filter_class->class_uppers, &size) != ERROR_SUCCESS) + { + memset(filter_class->class_uppers, 0, sizeof(filter_class->class_uppers)); + } + + size = sizeof(filter_class->class_lowers) - 1; + if (RegQueryValueExA(reg_class_hkey, "LowerFilters", NULL, ®_type, filter_class->class_lowers, &size) != ERROR_SUCCESS) + { + memset(filter_class->class_lowers, 0, sizeof(filter_class->class_lowers)); + } + return TRUE; +} diff --git a/external/libusb/src/registry.h b/external/libusb/src/registry.h new file mode 100644 index 00000000..1ce25e6b --- /dev/null +++ b/external/libusb/src/registry.h @@ -0,0 +1,221 @@ +/* libusb-win32, Generic Windows USB Library +* Copyright (c) 2002-2005 Stephan Meyer +* Copyright (c) 2010 Travis Robinson +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + + +#ifndef __USB_REGISTRY_H__ +#define __USB_REGISTRY_H__ + +#include +#include + + +#define LIBUSB_DRIVER_NAME_NT "libusb0" +#define LIBUSB_DRIVER_NAME_9X "libusb0.sys" + +typedef int bool_t; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!(FALSE)) +#endif + +#define REGISTRY_BUF_SIZE 512 + +typedef struct _filter_file_t filter_file_t; +struct _filter_file_t +{ + filter_file_t* next; + char name[MAX_PATH]; +}; + +typedef int filter_mode_e; +enum _filter_mode_e +{ + FM_NONE = 0, + FM_LIST = 1 << 0, + FM_INSTALL = 1 << 1, + FM_REMOVE = 1 << 2, +}; + +typedef int filter_type_e; +enum _filter_type_e +{ + FT_NONE = 0, + FT_CLASS_UPPERFILTER = 1 << 0, + FT_CLASS_LOWERFILTER = 1 << 1, + FT_DEVICE_UPPERFILTER = 1 << 2, + FT_DEVICE_LOWERFILTER = 1 << 3, +}; + +typedef struct _filter_hwid_t filter_hwid_t; +struct _filter_hwid_t +{ + int vid; + int pid; + int mi; + int rev; +}; + +typedef struct _filter_device_t filter_device_t; +struct _filter_device_t +{ + filter_device_t* next; + + char device_name[MAX_PATH]; + char device_hwid[MAX_PATH]; + char device_mfg[MAX_PATH]; + char device_uppers[MAX_PATH]; + char device_lowers[MAX_PATH]; + char device_id[MAX_PATH]; + + filter_type_e action; +}; + +typedef struct _filter_class_t filter_class_t; +struct _filter_class_t +{ + filter_class_t* next; + + char name[MAX_PATH]; // key + + char class_name[MAX_PATH]; + char class_guid[MAX_PATH]; + char class_uppers[MAX_PATH]; + char class_lowers[MAX_PATH]; + filter_device_t* class_filter_devices; + filter_type_e action; +}; + +typedef struct _filter_context_t filter_context_t; +struct _filter_context_t +{ + union + { + int switches_value; + struct + { + bool_t add_all_classes:1; + bool_t add_device_classes:1; + bool_t add_default_classes:1; + }; + }switches; + + filter_mode_e filter_mode; + filter_class_t* class_filters; + filter_device_t* device_filters; + filter_file_t* inf_files; + bool_t show_help_only; + bool_t remove_all_device_filters; + bool_t class_filters_modified; + char* prompt_string; + char* wait_string; +}; + +bool_t usb_registry_is_nt(void); + +bool_t usb_registry_restart_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data); +bool_t usb_registry_stop_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data); +bool_t usb_registry_start_device(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data); + +bool_t usb_registry_get_property(DWORD which, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char *buf, int size); +bool_t usb_registry_set_property(DWORD which, HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char *buf, int size); + +bool_t usb_registry_restart_all_devices(void); + + +void usb_registry_stop_libusb_devices(void); +void usb_registry_start_libusb_devices(void); + +bool_t usb_registry_get_mz_value(const char *key, const char *value, + char *buf, int size); +bool_t usb_registry_set_mz_value(const char *key, const char *value, + char *buf, int size); +int usb_registry_mz_string_size(const char *src); +char *usb_registry_mz_string_find(const char *src, const char *str, bool_t no_case); +char *usb_registry_mz_string_find_sub(const char *src, const char *str); +bool_t usb_registry_mz_string_insert(char *src, const char *str); +bool_t usb_registry_mz_string_remove(char *src, const char *str, bool_t no_case); +void usb_registry_mz_string_lower(char *src); + +bool_t usb_registry_get_hardware_id(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + char* max_path_buffer); +bool_t usb_registry_is_service_libusb(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + bool_t* is_libusb_service); +bool_t usb_registry_is_service_or_filter_libusb(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + bool_t* is_libusb_service); + +bool_t usb_registry_insert_class_filter(filter_context_t* filter_context); +bool_t usb_registry_remove_class_filter(filter_context_t* filter_context); +bool_t usb_registry_remove_device_filter(filter_context_t* filter_context); +bool_t usb_registry_free_class_keys(filter_class_t **head); +bool_t usb_registry_get_usb_class_keys(filter_context_t* filter_context, bool_t refresh_only); +bool_t usb_registry_get_all_class_keys(filter_context_t* filter_context, bool_t refresh_only); +bool_t usb_registry_get_device_filter_type(HDEVINFO dev_info, + SP_DEVINFO_DATA *dev_info_data, + filter_type_e* filter_type); + +bool_t usb_registry_add_usb_class_key(filter_context_t* filter_context, const char* class_guid); +bool_t usb_registry_add_filter_device_keys(filter_device_t** head, + const char* id, + const char* hwid, + const char* name, + const char* mfg, + const char* uppers_mz, + const char* lowers_mz, + filter_device_t** found); + +bool_t usb_registry_add_filter_file_keys(filter_file_t** head, + const char* name, + filter_file_t** found); + +bool_t usb_registry_lookup_class_keys_by_name(filter_class_t** head); +bool_t usb_registry_add_class_key(filter_class_t **head, + const char *key, + const char *class_name, + const char *class_guid, + filter_class_t **found, + bool_t update_only); + +bool_t usb_registry_insert_device_filters(filter_context_t* filter_context); +bool_t usb_registry_insert_device_filter(filter_context_t* filter_context, char* hwid, bool_t upper, + HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); + +bool_t usb_registry_free_filter_devices(filter_device_t **head); +bool_t usb_registry_free_filter_files(filter_file_t **head); + +filter_device_t* usb_registry_match_filter_device(filter_device_t** head, + HDEVINFO dev_info, PSP_DEVINFO_DATA dev_info_data); + +bool_t usb_registry_mz_to_sz(char* buf_mz, char separator); +bool_t usb_registry_fill_filter_hwid(const char* hwid, filter_hwid_t* filter_hwid); + +#endif diff --git a/external/libusb/src/usb.c b/external/libusb/src/usb.c new file mode 100644 index 00000000..60d74e9f --- /dev/null +++ b/external/libusb/src/usb.c @@ -0,0 +1,317 @@ +/* + * Main API entry point + * + * Copyright (c) 2000-2003 Johannes Erdfelt + * + * This library is covered by the LGPL, read LICENSE for details. + */ + +#include /* getenv */ +#include /* stderr */ +#include /* strcmp */ +#include + +#include "usbi.h" + +int usb_debug = 0; +struct usb_bus *_usb_busses = NULL; + +int usb_find_busses(void) +{ + struct usb_bus *busses, *bus; + int ret, changes = 0; + + ret = usb_os_find_busses(&busses); + if (ret < 0) + return ret; + + /* + * Now walk through all of the busses we know about and compare against + * this new list. Any duplicates will be removed from the new list. + * If we don't find it in the new list, the bus was removed. Any + * busses still in the new list, are new to us. + */ + bus = _usb_busses; + while (bus) + { + int found = 0; + struct usb_bus *nbus, *tbus = bus->next; + + nbus = busses; + while (nbus) + { + struct usb_bus *tnbus = nbus->next; + + if (!strcmp(bus->dirname, nbus->dirname)) + { + /* Remove it from the new busses list */ + LIST_DEL(busses, nbus); + + usb_free_bus(nbus); + found = 1; + break; + } + + nbus = tnbus; + } + + if (!found) + { + /* The bus was removed from the system */ + LIST_DEL(_usb_busses, bus); + usb_free_bus(bus); + changes++; + } + + bus = tbus; + } + + /* + * Anything on the *busses list is new. So add them to usb_busses and + * process them like the new bus it is. + */ + bus = busses; + while (bus) + { + struct usb_bus *tbus = bus->next; + + /* + * Remove it from the temporary list first and add it to the real + * usb_busses list. + */ + LIST_DEL(busses, bus); + + LIST_ADD(_usb_busses, bus); + + changes++; + + bus = tbus; + } + + return changes; +} + +int usb_find_devices(void) +{ + struct usb_bus *bus; + int ret, changes = 0; + + for (bus = usb_busses; bus; bus = bus->next) + { + struct usb_device *devices, *dev; + + /* Find all of the devices and put them into a temporary list */ + ret = usb_os_find_devices(bus, &devices); + if (ret < 0) + return ret; + + /* + * Now walk through all of the devices we know about and compare + * against this new list. Any duplicates will be removed from the new + * list. If we don't find it in the new list, the device was removed. + * Any devices still in the new list, are new to us. + */ + dev = bus->devices; + while (dev) + { + int found = 0; + struct usb_device *ndev, *tdev = dev->next; + + ndev = devices; + while (ndev) + { + struct usb_device *tndev = ndev->next; + + if (!strcmp(dev->filename, ndev->filename)) + { + /* Remove it from the new devices list */ + LIST_DEL(devices, ndev); + + usb_free_dev(ndev); + found = 1; + break; + } + + ndev = tndev; + } + + if (!found) + { + /* The device was removed from the system */ + LIST_DEL(bus->devices, dev); + usb_free_dev(dev); + changes++; + } + + dev = tdev; + } + + /* + * Anything on the *devices list is new. So add them to bus->devices and + * process them like the new device it is. + */ + dev = devices; + while (dev) + { + struct usb_device *tdev = dev->next; + + /* + * Remove it from the temporary list first and add it to the real + * bus->devices list. + */ + LIST_DEL(devices, dev); + + /* + * Some ports fetch the descriptors on scanning (like Linux) so we don't + * need to fetch them again. + */ + if (!dev->config) + { + usb_dev_handle *udev; + + udev = usb_open(dev); + if (udev) + { + usb_fetch_and_parse_descriptors(udev); + + usb_close(udev); + } + } + + // [ID:2928293 Tim Green] + // + if (dev->config) + { + LIST_ADD(bus->devices, dev); + changes++; + } + + dev = tdev; + } + + usb_os_determine_children(bus); + } + + return changes; +} + +void usb_init(void) +{ + if (getenv("USB_DEBUG")) + usb_set_debug(atoi(getenv("USB_DEBUG"))); + + usb_os_init(); +} + +usb_dev_handle *usb_open(struct usb_device *dev) +{ + usb_dev_handle *udev; + + udev = malloc(sizeof(*udev)); + if (!udev) + return NULL; + + udev->fd = -1; + udev->device = dev; + udev->bus = dev->bus; + udev->config = udev->interface = udev->altsetting = -1; + + if (usb_os_open(udev) < 0) + { + free(udev); + return NULL; + } + + return udev; +} + +int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen) +{ + /* + * We can't use usb_get_descriptor() because it's lacking the index + * parameter. This will be fixed in libusb 1.0 + */ + return usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, + (USB_DT_STRING << 8) + index, langid, buf, (int)buflen, 1000); +} + +int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen) +{ + char tbuf[255]; /* Some devices choke on size > 255 */ + int ret, langid, si, di; + + /* + * Asking for the zero'th index is special - it returns a string + * descriptor that contains all the language IDs supported by the + * device. Typically there aren't many - often only one. The + * language IDs are 16 bit numbers, and they start at the third byte + * in the descriptor. See USB 2.0 specification, section 9.6.7, for + * more information on this. */ + ret = usb_get_string(dev, 0, 0, tbuf, sizeof(tbuf)); + if (ret < 0) + return ret; + + if (ret < 4) + return -EIO; + + langid = tbuf[2] | (tbuf[3] << 8); + + ret = usb_get_string(dev, index, langid, tbuf, sizeof(tbuf)); + if (ret < 0) + return ret; + + if (tbuf[1] != USB_DT_STRING) + return -EIO; + + if (tbuf[0] > ret) + return -EFBIG; + + for (di = 0, si = 2; si < tbuf[0]; si += 2) + { + if (di >= ((int)buflen - 1)) + break; + + if (tbuf[si + 1]) /* high byte */ + buf[di++] = '?'; + else + buf[di++] = tbuf[si]; + } + + buf[di] = 0; + + return di; +} + +int usb_close(usb_dev_handle *dev) +{ + int ret; + + ret = usb_os_close(dev); + free(dev); + + return ret; +} + +struct usb_device *usb_device(usb_dev_handle *dev) +{ + return dev->device; +} + +void usb_free_dev(struct usb_device *dev) +{ + usb_destroy_configuration(dev); + free(dev->children); + free(dev); +} + +struct usb_bus *usb_get_busses(void) +{ + return _usb_busses; +} + +void usb_free_bus(struct usb_bus *bus) +{ + free(bus); +} + diff --git a/external/libusb/src/usbi.h b/external/libusb/src/usbi.h new file mode 100644 index 00000000..433623aa --- /dev/null +++ b/external/libusb/src/usbi.h @@ -0,0 +1,75 @@ +#ifndef _USBI_H_ +#define _USBI_H_ + +#include +#include "lusb0_usb.h" +#include "error.h" + +extern int usb_debug; + +/* Some quick and generic macros for the simple kind of lists we use */ +#define LIST_ADD(begin, ent) \ + do { \ + if (begin) { \ + ent->next = begin; \ + ent->next->prev = ent; \ + } else \ + ent->next = NULL; \ + ent->prev = NULL; \ + begin = ent; \ + } while(0) + +#define LIST_DEL(begin, ent) \ + do { \ + if (ent->prev) \ + ent->prev->next = ent->next; \ + else \ + begin = ent->next; \ + if (ent->next) \ + ent->next->prev = ent->prev; \ + ent->prev = NULL; \ + ent->next = NULL; \ + } while (0) + +#define DESC_HEADER_LENGTH 2 +#define DEVICE_DESC_LENGTH 18 +#define CONFIG_DESC_LENGTH 9 +#define INTERFACE_DESC_LENGTH 9 +#define ENDPOINT_DESC_LENGTH 7 +#define ENDPOINT_AUDIO_DESC_LENGTH 9 + +struct usb_dev_handle +{ + int fd; + + struct usb_bus *bus; + struct usb_device *device; + + int config; + int interface; + int altsetting; + + /* Added by RMT so implementations can store other per-open-device data */ + void *impl_info; +}; + +/* descriptors.c */ +int usb_parse_descriptor(unsigned char *source, char *description, void *dest); +int usb_parse_configuration(struct usb_config_descriptor *config, + unsigned char *buffer); +void usb_fetch_and_parse_descriptors(usb_dev_handle *udev); +void usb_destroy_configuration(struct usb_device *dev); + +/* OS specific routines */ +int usb_os_find_busses(struct usb_bus **busses); +int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices); +int usb_os_determine_children(struct usb_bus *bus); +void usb_os_init(void); +int usb_os_open(usb_dev_handle *dev); +int usb_os_close(usb_dev_handle *dev); + +void usb_free_dev(struct usb_device *dev); +void usb_free_bus(struct usb_bus *bus); + +#endif /* _USBI_H_ */ + diff --git a/external/libusb/src/windows.c b/external/libusb/src/windows.c new file mode 100644 index 00000000..b9a79a07 --- /dev/null +++ b/external/libusb/src/windows.c @@ -0,0 +1,1281 @@ +/* libusb-win32, Generic Windows USB Library + * Copyright (c) 2002-2005 Stephan Meyer + * Copyright (c) 2000-2005 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lusb0_usb.h" +#include "error.h" +#include "usbi.h" +#include "driver_api.h" +#include "registry.h" +#include "libusb-win32_version.h" + +#define LIBUSB_WIN32_DLL_LARGE_TRANSFER_SUPPORT + +#define LIBUSB_DEFAULT_TIMEOUT 5000 +#define LIBUSB_DEVICE_NAME "\\\\.\\libusb0-" +#define LIBUSB_BUS_NAME "bus-0" +#define LIBUSB_MAX_DEVICES 256 + +typedef struct +{ + usb_dev_handle *dev; + libusb_request req; + char *bytes; + int size; + DWORD control_code; + OVERLAPPED ol; +} usb_context_t; + + +static struct usb_version _usb_version = +{ + { VERSION_MAJOR, + VERSION_MINOR, + VERSION_MICRO, + VERSION_NANO }, + { -1, -1, -1, -1 } +}; + + +static int _usb_setup_async(usb_dev_handle *dev, void **context, + DWORD control_code, + unsigned char ep, int pktsize); +static int _usb_transfer_sync(usb_dev_handle *dev, int control_code, + int ep, int pktsize, char *bytes, int size, + int timeout); + +static int usb_get_configuration(usb_dev_handle *dev, bool_t cached); +static int _usb_cancel_io(usb_context_t *context); +static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep); + +static int _usb_io_sync(HANDLE dev, unsigned int code, void *in, int in_size, + void *out, int out_size, int *ret); +static int _usb_reap_async(void *context, int timeout, int cancel); +static int _usb_add_virtual_hub(struct usb_bus *bus); + +static void _usb_free_bus_list(struct usb_bus *bus); +static void _usb_free_dev_list(struct usb_device *dev); +static void _usb_deinit(void); + +/* DLL main entry point */ +BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + break; + case DLL_PROCESS_DETACH: + _usb_deinit(); + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + default: + break; + } + return TRUE; +} + + +static int usb_get_configuration(usb_dev_handle *dev, bool_t cached) +{ + int ret; + char config; + libusb_request request; + + if (cached) + { + memset(&request, 0, sizeof(request)); + request.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_GET_CACHED_CONFIGURATION, + &request, sizeof(request), &request, sizeof(request), &ret)) + { + USBERR("sending get cached configuration ioctl failed, win error: %s\n", usb_win_error_to_string()); + ret = -usb_win_error_to_errno(); + } + + if (ret < 1) + ret = -EINVAL; + else + config = *((char*)&request); + } + else + { + ret = usb_control_msg(dev, USB_RECIP_DEVICE | USB_ENDPOINT_IN, + USB_REQ_GET_CONFIGURATION, 0, 0, &config, 1, + LIBUSB_DEFAULT_TIMEOUT); + } + + if(ret < 0) + return ret; + + return config; +} + +int usb_os_open(usb_dev_handle *dev) +{ + char dev_name[LIBUSB_PATH_MAX]; + char *p; + int config; + if (!dev) + { + USBERR("invalid device handle %p", dev); + return -EINVAL; + } + + dev->impl_info = INVALID_HANDLE_VALUE; + dev->config = 0; + dev->interface = -1; + dev->altsetting = -1; + + if (!dev->device->filename) + { + USBERR0("invalid file name\n"); + return -ENOENT; + } + + /* build the Windows file name from the unique device name */ + strcpy(dev_name, dev->device->filename); + + p = strstr(dev_name, "--"); + + if (!p) + { + USBERR("invalid file name %s\n", dev->device->filename); + return -ENOENT; + } + + *p = 0; + + dev->impl_info = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR("failed to open %s: win error: %s", + dev->device->filename, usb_win_error_to_string()); + return -ENOENT; + } + + // get the cached configuration (no device i/o) + config = usb_get_configuration(dev, TRUE); + if (config > 0) + { + dev->config = config; + dev->interface = -1; + dev->altsetting = -1; + } + + return 0; +} + +int usb_os_close(usb_dev_handle *dev) +{ + if (dev->impl_info != INVALID_HANDLE_VALUE) + { + if (dev->interface >= 0) + { + usb_release_interface(dev, dev->interface); + } + + CloseHandle(dev->impl_info); + dev->impl_info = INVALID_HANDLE_VALUE; + dev->interface = -1; + dev->altsetting = -1; + } + + return 0; +} + +int usb_set_configuration(usb_dev_handle *dev, int configuration) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("error: device not open\n"); + return -EINVAL; + } + + if (dev->config == configuration) + { + return 0; + } + + if (dev->interface >= 0) + { + USBERR0("can't change configuration, an interface is still in use (claimed)\n"); + return -EINVAL; + } + + req.configuration.configuration = configuration; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_SET_CONFIGURATION, + &req, sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not set config %d: " + "win error: %s", configuration, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + dev->config = configuration; + dev->interface = -1; + dev->altsetting = -1; + + return 0; +} + +int usb_claim_interface(usb_dev_handle *dev, int interface) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + if (!dev->config) + { + USBERR("could not claim interface %d, invalid configuration %d\n", interface, dev->config); + return -EINVAL; + } + + if (dev->interface == interface) + { + return 0; + } + + req.intf.interface_number = interface; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_CLAIM_INTERFACE, + &req, sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not claim interface %d, " + "win error: %s", interface, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + else + { + dev->interface = interface; + dev->altsetting = 0; + return 0; + } +} + +int usb_release_interface(usb_dev_handle *dev, int interface) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + if (!dev->config) + { + USBERR("could not release interface %d, invalid configuration %d\n", interface, dev->config); + return -EINVAL; + } + + req.intf.interface_number = interface; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RELEASE_INTERFACE, + &req, sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not release interface %d, " + "win error: %s", interface, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + else + { + dev->interface = -1; + dev->altsetting = -1; + + return 0; + } +} + +int usb_set_altinterface(usb_dev_handle *dev, int alternate) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + if (dev->config <= 0) + { + USBERR("could not set alt interface %d: invalid configuration %d\n", alternate, dev->config); + return -EINVAL; + } + + if (dev->interface < 0) + { + USBERR("could not set alt interface %d: no interface claimed\n", alternate); + return -EINVAL; + } + + req.intf.interface_number = dev->interface; + req.intf.altsetting_number = alternate; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_SET_INTERFACE, + &req, sizeof(libusb_request), + NULL, 0, NULL)) + { + USBERR("could not set alt interface " + "%d/%d: win error: %s", + dev->interface, alternate, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + dev->altsetting = alternate; + + return 0; +} + +static int _usb_setup_async(usb_dev_handle *dev, void **context, + DWORD control_code, + unsigned char ep, int pktsize) +{ + usb_context_t **c = (usb_context_t **)context; + + if (((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE) + || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_WRITE)) + && (ep & USB_ENDPOINT_IN)) + { + USBERR("invalid endpoint 0x%02x", ep); + return -EINVAL; + } + + if (((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ) + || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_READ)) + && !(ep & USB_ENDPOINT_IN)) + { + USBERR("invalid endpoint 0x%02x\n", ep); + return -EINVAL; + } + + *c = malloc(sizeof(usb_context_t)); + + if (!*c) + { + USBERR0("memory allocation error\n"); + return -ENOMEM; + } + + memset(*c, 0, sizeof(usb_context_t)); + + (*c)->dev = dev; + (*c)->req.endpoint.endpoint = ep; + (*c)->req.endpoint.packet_size = pktsize; + (*c)->control_code = control_code; + + (*c)->ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (!(*c)->ol.hEvent) + { + free(*c); + *c = NULL; + USBERR("creating event failed: win error: %s", + usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +int usb_submit_async(void *context, char *bytes, int size) +{ + usb_context_t *c = (usb_context_t *)context; + + if (!c) + { + USBERR0("invalid context"); + return -EINVAL; + } + + if (c->dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + if (c->dev->config <= 0) + { + USBERR("invalid configuration %d\n", c->dev->config); + return -EINVAL; + } + + if (c->dev->interface < 0) + { + USBERR("invalid interface %d\n", c->dev->interface); + return -EINVAL; + } + + + c->ol.Offset = 0; + c->ol.OffsetHigh = 0; + c->bytes = bytes; + c->size = size; + + ResetEvent(c->ol.hEvent); + + if (!DeviceIoControl(c->dev->impl_info, + c->control_code, + &c->req, sizeof(libusb_request), + c->bytes, + c->size, NULL, &c->ol)) + { + if (GetLastError() != ERROR_IO_PENDING) + { + USBERR("submitting request failed, " + "win error: %s", usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + } + + return 0; +} + +static int _usb_reap_async(void *context, int timeout, int cancel) +{ + usb_context_t *c = (usb_context_t *)context; + ULONG ret = 0; + + if (!c) + { + USBERR0("invalid context\n"); + return -EINVAL; + } + + if (WaitForSingleObject(c->ol.hEvent, timeout) == WAIT_TIMEOUT) + { + /* request timed out */ + if (cancel) + { + _usb_cancel_io(c); + } + + USBERR0("timeout error\n"); + return -ETRANSFER_TIMEDOUT; + } + + if (!GetOverlappedResult(c->dev->impl_info, &c->ol, &ret, TRUE)) + { + USBERR("reaping request failed, win error: %s\n",usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return ret; +} + +int usb_reap_async(void *context, int timeout) +{ + return _usb_reap_async(context, timeout, TRUE); +} + +int usb_reap_async_nocancel(void *context, int timeout) +{ + return _usb_reap_async(context, timeout, FALSE); +} + + +int usb_cancel_async(void *context) +{ + /* NOTE that this function will cancel all pending URBs */ + /* on the same endpoint as this particular context, or even */ + /* all pending URBs for this particular device. */ + + usb_context_t *c = (usb_context_t *)context; + + if (!c) + { + USBERR0("invalid context\n"); + return -EINVAL; + } + + if (c->dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + _usb_cancel_io(c); + + return 0; +} + +int usb_free_async(void **context) +{ + usb_context_t **c = (usb_context_t **)context; + + if (!*c) + { + USBERR0("invalid context\n"); + return -EINVAL; + } + + CloseHandle((*c)->ol.hEvent); + + free(*c); + *c = NULL; + + return 0; +} + +static int _usb_transfer_sync(usb_dev_handle *dev, int control_code, + int ep, int pktsize, char *bytes, int size, + int timeout) +{ + void *context = NULL; + int transmitted = 0; + int ret; + int requested; + + if (!timeout) timeout=INFINITE; + ret = _usb_setup_async(dev, &context, control_code, (unsigned char )ep, + pktsize); + + if (ret < 0) + { + return ret; + } + + do + { +#ifdef LIBUSB_WIN32_DLL_LARGE_TRANSFER_SUPPORT + requested = size > LIBUSB_MAX_READ_WRITE ? LIBUSB_MAX_READ_WRITE : size; +#else + requested = size; +#endif + ret = usb_submit_async(context, bytes, requested); + + if (ret < 0) + { + transmitted = ret; + break; + } + + ret = usb_reap_async(context, timeout); + + if (ret < 0) + { + transmitted = ret; + break; + } + + transmitted += ret; + bytes += ret; + size -= ret; + } + while (size > 0 && ret == requested); + + usb_free_async(&context); + + return transmitted; +} + +int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) +{ + return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE, + ep, 0, bytes, size, timeout); +} + +int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) +{ + return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ, + ep, 0, bytes, size, timeout); +} + +int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) +{ + return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE, + ep, 0, bytes, size, timeout); +} + +int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) +{ + return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ, + ep, 0, bytes, size, timeout); +} + +int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize) +{ + if (ep & 0x80) + return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_READ, + ep, pktsize); + else + return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_WRITE, + ep, pktsize); +} + +int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep) +{ + if (ep & 0x80) + return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ, + ep, 0); + else + return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE, + ep, 0); +} + +int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep) +{ + if (ep & 0x80) + return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ, + ep, 0); + else + return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE, + ep, 0); +} + +int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, int timeout) +{ + int read = 0; + libusb_request req; + void *out = &req; + int out_size = sizeof(libusb_request); + void *in = bytes; + int in_size = size; + int code; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + req.timeout = timeout; + + /* windows doesn't support generic control messages, so it needs to be */ + /* split up */ + switch (requesttype & (0x03 << 5)) + { + case USB_TYPE_STANDARD: + switch (request) + { + case USB_REQ_GET_STATUS: + req.status.recipient = requesttype & 0x1F; + req.status.index = index; + code = LIBUSB_IOCTL_GET_STATUS; + break; + + case USB_REQ_CLEAR_FEATURE: + req.feature.recipient = requesttype & 0x1F; + req.feature.feature = value; + req.feature.index = index; + code = LIBUSB_IOCTL_CLEAR_FEATURE; + break; + + case USB_REQ_SET_FEATURE: + req.feature.recipient = requesttype & 0x1F; + req.feature.feature = value; + req.feature.index = index; + code = LIBUSB_IOCTL_SET_FEATURE; + break; + + case USB_REQ_GET_DESCRIPTOR: + req.descriptor.recipient = requesttype & 0x1F; + req.descriptor.type = (value >> 8) & 0xFF; + req.descriptor.index = value & 0xFF; + req.descriptor.language_id = index; + code = LIBUSB_IOCTL_GET_DESCRIPTOR; + break; + + case USB_REQ_SET_DESCRIPTOR: + req.descriptor.recipient = requesttype & 0x1F; + req.descriptor.type = (value >> 8) & 0xFF; + req.descriptor.index = value & 0xFF; + req.descriptor.language_id = index; + code = LIBUSB_IOCTL_SET_DESCRIPTOR; + break; + + case USB_REQ_GET_CONFIGURATION: + code = LIBUSB_IOCTL_GET_CONFIGURATION; + break; + + case USB_REQ_SET_CONFIGURATION: + req.configuration.configuration = value; + code = LIBUSB_IOCTL_SET_CONFIGURATION; + break; + + case USB_REQ_GET_INTERFACE: + req.intf.interface_number = index; + code = LIBUSB_IOCTL_GET_INTERFACE; + break; + + case USB_REQ_SET_INTERFACE: + req.intf.interface_number = index; + req.intf.altsetting_number = value; + code = LIBUSB_IOCTL_SET_INTERFACE; + break; + + default: + USBERR("invalid request 0x%x", request); + return -EINVAL; + } + break; + + case USB_TYPE_VENDOR: + case USB_TYPE_CLASS: + + req.vendor.type = (requesttype >> 5) & 0x03; + req.vendor.recipient = requesttype & 0x1F; + req.vendor.request = request; + req.vendor.value = value; + req.vendor.index = index; + + if (requesttype & 0x80) + code = LIBUSB_IOCTL_VENDOR_READ; + else + code = LIBUSB_IOCTL_VENDOR_WRITE; + break; + + case USB_TYPE_RESERVED: + default: + USBERR("invalid or unsupported request type: %x", + requesttype); + return -EINVAL; + } + + /* out request? */ + if (!(requesttype & USB_ENDPOINT_IN)) + { + if (!(out = malloc(sizeof(libusb_request) + size))) + { + USBERR0("memory allocation failed\n"); + return -ENOMEM; + } + + memcpy(out, &req, sizeof(libusb_request)); + memcpy((char *)out + sizeof(libusb_request), bytes, size); + out_size = sizeof(libusb_request) + size; + in = NULL; + in_size = 0; + } + + if (!_usb_io_sync(dev->impl_info, code, out, out_size, in, in_size, &read)) + { + USBERR("sending control message failed, win error: %s\n", usb_win_error_to_string()); + if (!(requesttype & USB_ENDPOINT_IN)) + { + free(out); + } + return -usb_win_error_to_errno(); + } + + /* out request? */ + if (!(requesttype & USB_ENDPOINT_IN)) + { + free(out); + return size; + } + else + return read; +} + + +int usb_os_find_busses(struct usb_bus **busses) +{ + struct usb_bus *bus = NULL; + + /* create one 'virtual' bus */ + + bus = malloc(sizeof(struct usb_bus)); + + if (!bus) + { + USBERR0("memory allocation failed\n"); + return -ENOMEM; + } + + memset(bus, 0, sizeof(*bus)); + strcpy(bus->dirname, LIBUSB_BUS_NAME); + + USBMSG("found %s\n", bus->dirname); + + *busses = bus; + + return 0; +} + +int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices) +{ + int i; + struct usb_device *dev, *fdev = NULL; + char dev_name[LIBUSB_PATH_MAX]; + int ret; + HANDLE handle; + libusb_request req; + + for (i = 1; i < LIBUSB_MAX_DEVICES; i++) + { + ret = 0; + + _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", + LIBUSB_DEVICE_NAME, i); + + if (!(dev = malloc(sizeof(*dev)))) + { + USBERR0("memory allocation failed\n"); + return -ENOMEM; + } + + memset(dev, 0, sizeof(*dev)); + dev->bus = bus; + dev->devnum = (unsigned char)i; + + handle = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (handle == INVALID_HANDLE_VALUE) + { + free(dev); + continue; + } + + /* retrieve device descriptor */ + req.descriptor.type = USB_DT_DEVICE; + req.descriptor.recipient = USB_RECIP_DEVICE; + req.descriptor.index = 0; + req.descriptor.language_id = 0; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + _usb_io_sync(handle, LIBUSB_IOCTL_GET_DESCRIPTOR, + &req, sizeof(libusb_request), + &dev->descriptor, USB_DT_DEVICE_SIZE, &ret); + + if (ret < USB_DT_DEVICE_SIZE) + { + USBERR0("couldn't read device descriptor\n"); + free(dev); + CloseHandle(handle); + continue; + } + + _snprintf(dev->filename, LIBUSB_PATH_MAX - 1, "%s--0x%04x-0x%04x", + dev_name, dev->descriptor.idVendor, dev->descriptor.idProduct); + + CloseHandle(handle); + + LIST_ADD(fdev, dev); + + USBMSG("found %s on %s\n", dev->filename, bus->dirname); + } + + *devices = fdev; + + return 0; +} + + +void usb_os_init(void) +{ + HANDLE dev; + libusb_request req; + int i; + int ret; + char dev_name[LIBUSB_PATH_MAX]; + + USBMSG("dll version: %d.%d.%d.%d\n", + VERSION_MAJOR, VERSION_MINOR, + VERSION_MICRO, VERSION_NANO); + + + for (i = 1; i < LIBUSB_MAX_DEVICES; i++) + { + /* build the Windows file name */ + _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", + LIBUSB_DEVICE_NAME, i); + + dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (dev == INVALID_HANDLE_VALUE) + { + continue; + } + + if (!_usb_io_sync(dev, LIBUSB_IOCTL_GET_VERSION, + &req, sizeof(libusb_request), + &req, sizeof(libusb_request), &ret) + || (ret < sizeof(libusb_request))) + { + USBERR0("getting driver version failed\n"); + CloseHandle(dev); + continue; + } + else + { + _usb_version.driver.major = req.version.major; + _usb_version.driver.minor = req.version.minor; + _usb_version.driver.micro = req.version.micro; + _usb_version.driver.nano = req.version.nano; + + USBMSG("driver version: %d.%d.%d.%d\n", + req.version.major, req.version.minor, + req.version.micro, req.version.nano); + + /* set debug level */ + req.timeout = 0; + req.debug.level = usb_log_get_level(); + + if (!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, + &req, sizeof(libusb_request), + NULL, 0, NULL)) + { + USBERR0("setting debug level failed"); + } + + CloseHandle(dev); + break; + } + } +} + + +int usb_resetep(usb_dev_handle *dev, unsigned int ep) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + req.endpoint.endpoint = (int)ep; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &req, + sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not abort ep 0x%02x, win error: %s\n", ep, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &req, + sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not reset ep 0x%02x, win error: %s\n", ep, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +int usb_clear_halt(usb_dev_handle *dev, unsigned int ep) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + req.endpoint.endpoint = (int)ep; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &req, + sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not clear halt, ep 0x%02x, " + "win error: %s", ep, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +int usb_reset(usb_dev_handle *dev) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_DEVICE, + &req, sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not reset device, win error: %s\n", usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +int usb_reset_ex(usb_dev_handle *dev, unsigned int reset_type) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open\n"); + return -EINVAL; + } + + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + req.reset_ex.reset_type = reset_type; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_DEVICE_EX, + &req, sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not reset device, win error: %s\n", usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +const struct usb_version *usb_get_version(void) +{ + return &_usb_version; +} + +void usb_set_debug(int level) +{ + HANDLE dev; + libusb_request req; + int i; + char dev_name[LIBUSB_PATH_MAX]; + + if (usb_log_get_level() || level) + { + USBMSG("setting debugging level to %d (%s)\n", + level, level ? "on" : "off"); + } + + usb_log_set_level(level); + + /* find a valid device */ + for (i = 1; i < LIBUSB_MAX_DEVICES; i++) + { + /* build the Windows file name */ + _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", + LIBUSB_DEVICE_NAME, i); + + dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (dev == INVALID_HANDLE_VALUE) + { + continue; + } + + /* set debug level */ + req.timeout = 0; + req.debug.level = usb_log_get_level(); + + if (!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, + &req, sizeof(libusb_request), + NULL, 0, NULL)) + { + USBERR0("setting debug level failed\n"); + } + + CloseHandle(dev); + + break; + } +} + +int usb_os_determine_children(struct usb_bus *bus) +{ + struct usb_device *dev; + int i = 0; + + /* add a virtual hub to the bus to emulate this feature */ + if (_usb_add_virtual_hub(bus)) + { + if (bus->root_dev->children) + { + free(bus->root_dev->children); + } + + bus->root_dev->num_children = 0; + for (dev = bus->devices; dev; dev = dev->next) + bus->root_dev->num_children++; + + bus->root_dev->children + = malloc(sizeof(struct usb_device *) * bus->root_dev->num_children); + + for (dev = bus->devices; dev; dev = dev->next) + bus->root_dev->children[i++] = dev; + } + + return 0; +} + +static int _usb_cancel_io(usb_context_t *context) +{ + int ret; + ret = _usb_abort_ep(context->dev, context->req.endpoint.endpoint); + WaitForSingleObject(context->ol.hEvent, 0); + return ret; +} + +static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep) +{ + libusb_request req; + + if (dev->impl_info == INVALID_HANDLE_VALUE) + { + USBERR0("device not open"); + return -EINVAL; + } + + req.endpoint.endpoint = (int)ep; + req.timeout = LIBUSB_DEFAULT_TIMEOUT; + + if (!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &req, + sizeof(libusb_request), NULL, 0, NULL)) + { + USBERR("could not abort ep 0x%02x, win error: %s\n", ep, usb_win_error_to_string()); + return -usb_win_error_to_errno(); + } + + return 0; +} + +static int _usb_io_sync(HANDLE dev, unsigned int code, void *out, int out_size, + void *in, int in_size, int *ret) +{ + OVERLAPPED ol; + DWORD _ret; + + memset(&ol, 0, sizeof(ol)); + + if (ret) + *ret = 0; + + ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (!ol.hEvent) + return FALSE; + + if (!DeviceIoControl(dev, code, out, out_size, in, in_size, NULL, &ol)) + { + if (GetLastError() != ERROR_IO_PENDING) + { + CloseHandle(ol.hEvent); + return FALSE; + } + } + + if (GetOverlappedResult(dev, &ol, &_ret, TRUE)) + { + if (ret) + *ret = (int)_ret; + CloseHandle(ol.hEvent); + return TRUE; + } + + CloseHandle(ol.hEvent); + return FALSE; +} + +static int _usb_add_virtual_hub(struct usb_bus *bus) +{ + struct usb_device *dev; + + if (!bus->root_dev) + { + if (!(dev = malloc(sizeof(*dev)))) + return FALSE; + + memset(dev, 0, sizeof(*dev)); + strcpy(dev->filename, "virtual-hub"); + dev->bus = bus; + + dev->descriptor.bLength = USB_DT_DEVICE_SIZE; + dev->descriptor.bDescriptorType = USB_DT_DEVICE; + dev->descriptor.bcdUSB = 0x0200; + dev->descriptor.bDeviceClass = USB_CLASS_HUB; + dev->descriptor.bDeviceSubClass = 0; + dev->descriptor.bDeviceProtocol = 0; + dev->descriptor.bMaxPacketSize0 = 64; + dev->descriptor.idVendor = 0; + dev->descriptor.idProduct = 0; + dev->descriptor.bcdDevice = 0x100; + dev->descriptor.iManufacturer = 0; + dev->descriptor.iProduct = 0; + dev->descriptor.iSerialNumber = 0; + dev->descriptor.bNumConfigurations = 0; + + bus->root_dev = dev; + } + + return TRUE; +} + +static void _usb_free_bus_list(struct usb_bus *bus) +{ + if (bus) + { + _usb_free_bus_list(bus->next); + if (bus->root_dev) + usb_free_dev(bus->root_dev); + _usb_free_dev_list(bus->devices); + usb_free_bus(bus); + } +} + +static void _usb_free_dev_list(struct usb_device *dev) +{ + if (dev) + { + _usb_free_dev_list(dev->next); + usb_free_dev(dev); + } +} + +static void _usb_deinit(void) +{ + _usb_free_bus_list(usb_get_busses()); +} diff --git a/flip2.c b/flip2.c index ba90086a..d59147e2 100644 --- a/flip2.c +++ b/flip2.c @@ -617,7 +617,7 @@ int flip2_read_memory(struct dfu_dev *dfu, return -1; } - ptr += read_size; + ptr = (char*)ptr + read_size; addr += read_size; size -= read_size; } @@ -680,7 +680,7 @@ int flip2_write_memory(struct dfu_dev *dfu, return -1; } - ptr += write_size; + ptr = (const char*)ptr + write_size; addr += write_size; size -= write_size; } diff --git a/ft245r.c b/ft245r.c index 7f9883f1..80aed028 100644 --- a/ft245r.c +++ b/ft245r.c @@ -82,7 +82,11 @@ /* ftdi.h includes usb.h */ #include #else +#ifdef _MSC_VER +#pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.") +#else #warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again. +#endif #define DO_NOT_BUILD_FT245R #endif diff --git a/lists.c b/lists.c index cab88364..aa87ff40 100644 --- a/lists.c +++ b/lists.c @@ -40,6 +40,7 @@ #include #include +#include "avrdude.h" #include "libavrdude.h" #define MAGIC 0xb05b05b0 diff --git a/main.c b/main.c index 1de907c8..0b0bd4f8 100644 --- a/main.c +++ b/main.c @@ -133,7 +133,7 @@ static void usage(void) " -q Quell progress output. -q -q for less.\n" " -l logfile Use logfile rather than stderr for diagnostics.\n" " -? Display this usage.\n" - "\navrdude version %s, URL: \n" + "\navrdude version %s, URL: \n" ,progname, version); } diff --git a/msvc/generated/ac_cfg.h b/msvc/generated/ac_cfg.h new file mode 100644 index 00000000..366e64ee --- /dev/null +++ b/msvc/generated/ac_cfg.h @@ -0,0 +1,201 @@ +/* ac_cfg.h. Generated from ac_cfg.h.in by configure. */ +/* ac_cfg.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DDK_HIDSDI_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +/* #undef HAVE_GETADDRINFO */ + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_HIDAPI_HIDAPI_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if ELF support is enabled via libelf */ +#define HAVE_LIBELF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBELF_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBELF_LIBELF_H */ + +/* Define if FTDI support is enabled via libftdi */ +/* #undef HAVE_LIBFTDI */ + +/* Define if FTDI support is enabled via libftdi1 */ +/* #undef HAVE_LIBFTDI1 */ + +/* Define if libftdi supports FT232H, libftdi version >= 0.20 */ +/* #undef HAVE_LIBFTDI_TYPE_232H */ + +/* Define if HID support is enabled via the Win32 DDK */ +#define HAVE_LIBHID 1 + +/* Define if HID support is enabled via libhidapi */ +#define HAVE_LIBHIDAPI 1 + +/* Define to 1 if you have the `ncurses' library (-lncurses). */ +/* #undef HAVE_LIBNCURSES */ + +/* Define to 1 if you have the `readline' library (-lreadline). */ +/* #undef HAVE_LIBREADLINE */ + +/* Define to 1 if you have the `termcap' library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define if USB support is enabled via libusb */ +#define HAVE_LIBUSB 1 + +/* Define if USB support is enabled via a libusb-1.0 compatible libusb */ +/* #undef HAVE_LIBUSB_1_0 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUSB_1_0_LIBUSB_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUSB_H */ + +/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ +#define HAVE_LIBWS2_32 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Linux sysfs GPIO support enabled */ +/* #undef HAVE_LINUXGPIO */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LUSB0_USB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETINET_IN_H */ + +/* parallel port access enabled */ +/* #undef HAVE_PARPORT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTHREAD_H */ + +/* Define to 1 if you have the `select' function. */ +/* #undef HAVE_SELECT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strncasecmp' function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_IOCTL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIOS_H */ + +/* Define to 1 if the system has the type `uint_t'. */ +/* #undef HAVE_UINT_T */ + +/* Define to 1 if the system has the type `ulong_t'. */ +/* #undef HAVE_ULONG_T */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_USB_H */ + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Define if lex/flex has yylex_destroy */ +#define HAVE_YYLEX_DESTROY 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* #undef LT_OBJDIR */ + +/* Name of package */ +#define PACKAGE "avrdude" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "avrdude-dev@nongnu.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "avrdude" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "avrdude 6.3.1.0-windows" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "avrdude" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "6.3.1.0-windows" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "6.3.1.0-windows" + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#define YYTEXT_POINTER 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff --git a/msvc/generated/config_gram.c b/msvc/generated/config_gram.c new file mode 100644 index 00000000..dfae0428 --- /dev/null +++ b/msvc/generated/config_gram.c @@ -0,0 +1,3861 @@ +/* A Bison parser, made by GNU Bison 3.5.1. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.5.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 21 "config_gram.y" + + +#include "ac_cfg.h" + +#include +#include +#include + +#include "avrdude.h" +#include "libavrdude.h" +#include "config.h" + +#if defined(WIN32NATIVE) +#define strtok_r( _s, _sep, _lasts ) \ + ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +int yylex(void); +int yyerror(char * errmsg, ...); +int yywarning(char * errmsg, ...); + +static int assign_pin(int pinno, TOKEN * v, int invert); +static int assign_pin_list(int invert); +static int which_opcode(TOKEN * opcode); +static int parse_cmdbits(OPCODE * op); + +static int pin_name; + +#line 102 "config_gram.c" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Use api.header.include to #include this header + instead of duplicating it here. */ +#ifndef YY_YY_CONFIG_GRAM_H_INCLUDED +# define YY_YY_CONFIG_GRAM_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + K_READ = 258, + K_WRITE = 259, + K_READ_LO = 260, + K_READ_HI = 261, + K_WRITE_LO = 262, + K_WRITE_HI = 263, + K_LOADPAGE_LO = 264, + K_LOADPAGE_HI = 265, + K_LOAD_EXT_ADDR = 266, + K_WRITEPAGE = 267, + K_CHIP_ERASE = 268, + K_PGM_ENABLE = 269, + K_MEMORY = 270, + K_PAGE_SIZE = 271, + K_PAGED = 272, + K_BAUDRATE = 273, + K_BS2 = 274, + K_BUFF = 275, + K_CHIP_ERASE_DELAY = 276, + K_CONNTYPE = 277, + K_DEDICATED = 278, + K_DEFAULT_BITCLOCK = 279, + K_DEFAULT_PARALLEL = 280, + K_DEFAULT_PROGRAMMER = 281, + K_DEFAULT_SAFEMODE = 282, + K_DEFAULT_SERIAL = 283, + K_DESC = 284, + K_FAMILY_ID = 285, + K_DEVICECODE = 286, + K_STK500_DEVCODE = 287, + K_AVR910_DEVCODE = 288, + K_EEPROM = 289, + K_ERRLED = 290, + K_FLASH = 291, + K_ID = 292, + K_IO = 293, + K_LOADPAGE = 294, + K_MAX_WRITE_DELAY = 295, + K_MCU_BASE = 296, + K_MIN_WRITE_DELAY = 297, + K_MISO = 298, + K_MOSI = 299, + K_NUM_PAGES = 300, + K_NVM_BASE = 301, + K_OCD_BASE = 302, + K_OCDREV = 303, + K_OFFSET = 304, + K_PAGEL = 305, + K_PARALLEL = 306, + K_PARENT = 307, + K_PART = 308, + K_PGMLED = 309, + K_PROGRAMMER = 310, + K_PSEUDO = 311, + K_PWROFF_AFTER_WRITE = 312, + K_RDYLED = 313, + K_READBACK_P1 = 314, + K_READBACK_P2 = 315, + K_READMEM = 316, + K_RESET = 317, + K_RETRY_PULSE = 318, + K_SERIAL = 319, + K_SCK = 320, + K_SIGNATURE = 321, + K_SIZE = 322, + K_USB = 323, + K_USBDEV = 324, + K_USBSN = 325, + K_USBPID = 326, + K_USBPRODUCT = 327, + K_USBVENDOR = 328, + K_USBVID = 329, + K_TYPE = 330, + K_VCC = 331, + K_VFYLED = 332, + K_NO = 333, + K_YES = 334, + K_TIMEOUT = 335, + K_STABDELAY = 336, + K_CMDEXEDELAY = 337, + K_HVSPCMDEXEDELAY = 338, + K_SYNCHLOOPS = 339, + K_BYTEDELAY = 340, + K_POLLVALUE = 341, + K_POLLINDEX = 342, + K_PREDELAY = 343, + K_POSTDELAY = 344, + K_POLLMETHOD = 345, + K_MODE = 346, + K_DELAY = 347, + K_BLOCKSIZE = 348, + K_READSIZE = 349, + K_HVENTERSTABDELAY = 350, + K_PROGMODEDELAY = 351, + K_LATCHCYCLES = 352, + K_TOGGLEVTG = 353, + K_POWEROFFDELAY = 354, + K_RESETDELAYMS = 355, + K_RESETDELAYUS = 356, + K_HVLEAVESTABDELAY = 357, + K_RESETDELAY = 358, + K_SYNCHCYCLES = 359, + K_HVCMDEXEDELAY = 360, + K_CHIPERASEPULSEWIDTH = 361, + K_CHIPERASEPOLLTIMEOUT = 362, + K_CHIPERASETIME = 363, + K_PROGRAMFUSEPULSEWIDTH = 364, + K_PROGRAMFUSEPOLLTIMEOUT = 365, + K_PROGRAMLOCKPULSEWIDTH = 366, + K_PROGRAMLOCKPOLLTIMEOUT = 367, + K_PP_CONTROLSTACK = 368, + K_HVSP_CONTROLSTACK = 369, + K_ALLOWFULLPAGEBITSTREAM = 370, + K_ENABLEPAGEPROGRAMMING = 371, + K_HAS_JTAG = 372, + K_HAS_DW = 373, + K_HAS_PDI = 374, + K_HAS_UPDI = 375, + K_HAS_TPI = 376, + K_IDR = 377, + K_IS_AT90S1200 = 378, + K_IS_AVR32 = 379, + K_RAMPZ = 380, + K_SPMCR = 381, + K_EECR = 382, + K_FLASH_INSTR = 383, + K_EEPROM_INSTR = 384, + TKN_COMMA = 385, + TKN_EQUAL = 386, + TKN_SEMI = 387, + TKN_TILDE = 388, + TKN_LEFT_PAREN = 389, + TKN_RIGHT_PAREN = 390, + TKN_NUMBER = 391, + TKN_NUMBER_REAL = 392, + TKN_STRING = 393 + }; +#endif +/* Tokens. */ +#define K_READ 258 +#define K_WRITE 259 +#define K_READ_LO 260 +#define K_READ_HI 261 +#define K_WRITE_LO 262 +#define K_WRITE_HI 263 +#define K_LOADPAGE_LO 264 +#define K_LOADPAGE_HI 265 +#define K_LOAD_EXT_ADDR 266 +#define K_WRITEPAGE 267 +#define K_CHIP_ERASE 268 +#define K_PGM_ENABLE 269 +#define K_MEMORY 270 +#define K_PAGE_SIZE 271 +#define K_PAGED 272 +#define K_BAUDRATE 273 +#define K_BS2 274 +#define K_BUFF 275 +#define K_CHIP_ERASE_DELAY 276 +#define K_CONNTYPE 277 +#define K_DEDICATED 278 +#define K_DEFAULT_BITCLOCK 279 +#define K_DEFAULT_PARALLEL 280 +#define K_DEFAULT_PROGRAMMER 281 +#define K_DEFAULT_SAFEMODE 282 +#define K_DEFAULT_SERIAL 283 +#define K_DESC 284 +#define K_FAMILY_ID 285 +#define K_DEVICECODE 286 +#define K_STK500_DEVCODE 287 +#define K_AVR910_DEVCODE 288 +#define K_EEPROM 289 +#define K_ERRLED 290 +#define K_FLASH 291 +#define K_ID 292 +#define K_IO 293 +#define K_LOADPAGE 294 +#define K_MAX_WRITE_DELAY 295 +#define K_MCU_BASE 296 +#define K_MIN_WRITE_DELAY 297 +#define K_MISO 298 +#define K_MOSI 299 +#define K_NUM_PAGES 300 +#define K_NVM_BASE 301 +#define K_OCD_BASE 302 +#define K_OCDREV 303 +#define K_OFFSET 304 +#define K_PAGEL 305 +#define K_PARALLEL 306 +#define K_PARENT 307 +#define K_PART 308 +#define K_PGMLED 309 +#define K_PROGRAMMER 310 +#define K_PSEUDO 311 +#define K_PWROFF_AFTER_WRITE 312 +#define K_RDYLED 313 +#define K_READBACK_P1 314 +#define K_READBACK_P2 315 +#define K_READMEM 316 +#define K_RESET 317 +#define K_RETRY_PULSE 318 +#define K_SERIAL 319 +#define K_SCK 320 +#define K_SIGNATURE 321 +#define K_SIZE 322 +#define K_USB 323 +#define K_USBDEV 324 +#define K_USBSN 325 +#define K_USBPID 326 +#define K_USBPRODUCT 327 +#define K_USBVENDOR 328 +#define K_USBVID 329 +#define K_TYPE 330 +#define K_VCC 331 +#define K_VFYLED 332 +#define K_NO 333 +#define K_YES 334 +#define K_TIMEOUT 335 +#define K_STABDELAY 336 +#define K_CMDEXEDELAY 337 +#define K_HVSPCMDEXEDELAY 338 +#define K_SYNCHLOOPS 339 +#define K_BYTEDELAY 340 +#define K_POLLVALUE 341 +#define K_POLLINDEX 342 +#define K_PREDELAY 343 +#define K_POSTDELAY 344 +#define K_POLLMETHOD 345 +#define K_MODE 346 +#define K_DELAY 347 +#define K_BLOCKSIZE 348 +#define K_READSIZE 349 +#define K_HVENTERSTABDELAY 350 +#define K_PROGMODEDELAY 351 +#define K_LATCHCYCLES 352 +#define K_TOGGLEVTG 353 +#define K_POWEROFFDELAY 354 +#define K_RESETDELAYMS 355 +#define K_RESETDELAYUS 356 +#define K_HVLEAVESTABDELAY 357 +#define K_RESETDELAY 358 +#define K_SYNCHCYCLES 359 +#define K_HVCMDEXEDELAY 360 +#define K_CHIPERASEPULSEWIDTH 361 +#define K_CHIPERASEPOLLTIMEOUT 362 +#define K_CHIPERASETIME 363 +#define K_PROGRAMFUSEPULSEWIDTH 364 +#define K_PROGRAMFUSEPOLLTIMEOUT 365 +#define K_PROGRAMLOCKPULSEWIDTH 366 +#define K_PROGRAMLOCKPOLLTIMEOUT 367 +#define K_PP_CONTROLSTACK 368 +#define K_HVSP_CONTROLSTACK 369 +#define K_ALLOWFULLPAGEBITSTREAM 370 +#define K_ENABLEPAGEPROGRAMMING 371 +#define K_HAS_JTAG 372 +#define K_HAS_DW 373 +#define K_HAS_PDI 374 +#define K_HAS_UPDI 375 +#define K_HAS_TPI 376 +#define K_IDR 377 +#define K_IS_AT90S1200 378 +#define K_IS_AVR32 379 +#define K_RAMPZ 380 +#define K_SPMCR 381 +#define K_EECR 382 +#define K_FLASH_INSTR 383 +#define K_EEPROM_INSTR 384 +#define TKN_COMMA 385 +#define TKN_EQUAL 386 +#define TKN_SEMI 387 +#define TKN_TILDE 388 +#define TKN_LEFT_PAREN 389 +#define TKN_RIGHT_PAREN 390 +#define TKN_NUMBER 391 +#define TKN_NUMBER_REAL 392 +#define TKN_STRING 393 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_CONFIG_GRAM_H_INCLUDED */ + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + +/* Stored state numbers (used for stacks). */ +typedef yytype_int16 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 22 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 409 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 139 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 45 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 185 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 427 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 393 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 214, 214, 220, 224, 225, 229, 230, 235, 237, + 239, 245, 251, 257, 262, 273, 306, 316, 338, 396, + 406, 429, 430, 435, 436, 440, 441, 445, 468, 470, + 472, 474, 476, 481, 490, 494, 504, 512, 516, 517, + 518, 522, 529, 535, 536, 543, 550, 560, 575, 588, + 590, 594, 596, 600, 602, 606, 608, 613, 615, 619, + 619, 620, 620, 621, 621, 622, 622, 623, 623, 624, + 624, 625, 625, 626, 626, 627, 627, 628, 628, 632, + 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, + 643, 648, 649, 654, 654, 658, 658, 662, 662, 666, + 673, 680, 687, 695, 702, 709, 720, 727, 758, 789, + 819, 849, 855, 861, 867, 877, 883, 889, 895, 901, + 907, 913, 919, 925, 931, 937, 943, 949, 955, 961, + 967, 973, 979, 985, 991, 997, 1003, 1009, 1015, 1021, + 1027, 1033, 1039, 1045, 1055, 1065, 1075, 1085, 1095, 1105, + 1115, 1125, 1135, 1141, 1147, 1153, 1159, 1165, 1171, 1177, + 1183, 1193, 1212, 1236, 1235, 1260, 1287, 1287, 1292, 1293, + 1298, 1304, 1311, 1317, 1323, 1329, 1335, 1341, 1347, 1353, + 1360, 1366, 1372, 1378, 1384, 1391 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "K_READ", "K_WRITE", "K_READ_LO", + "K_READ_HI", "K_WRITE_LO", "K_WRITE_HI", "K_LOADPAGE_LO", + "K_LOADPAGE_HI", "K_LOAD_EXT_ADDR", "K_WRITEPAGE", "K_CHIP_ERASE", + "K_PGM_ENABLE", "K_MEMORY", "K_PAGE_SIZE", "K_PAGED", "K_BAUDRATE", + "K_BS2", "K_BUFF", "K_CHIP_ERASE_DELAY", "K_CONNTYPE", "K_DEDICATED", + "K_DEFAULT_BITCLOCK", "K_DEFAULT_PARALLEL", "K_DEFAULT_PROGRAMMER", + "K_DEFAULT_SAFEMODE", "K_DEFAULT_SERIAL", "K_DESC", "K_FAMILY_ID", + "K_DEVICECODE", "K_STK500_DEVCODE", "K_AVR910_DEVCODE", "K_EEPROM", + "K_ERRLED", "K_FLASH", "K_ID", "K_IO", "K_LOADPAGE", "K_MAX_WRITE_DELAY", + "K_MCU_BASE", "K_MIN_WRITE_DELAY", "K_MISO", "K_MOSI", "K_NUM_PAGES", + "K_NVM_BASE", "K_OCD_BASE", "K_OCDREV", "K_OFFSET", "K_PAGEL", + "K_PARALLEL", "K_PARENT", "K_PART", "K_PGMLED", "K_PROGRAMMER", + "K_PSEUDO", "K_PWROFF_AFTER_WRITE", "K_RDYLED", "K_READBACK_P1", + "K_READBACK_P2", "K_READMEM", "K_RESET", "K_RETRY_PULSE", "K_SERIAL", + "K_SCK", "K_SIGNATURE", "K_SIZE", "K_USB", "K_USBDEV", "K_USBSN", + "K_USBPID", "K_USBPRODUCT", "K_USBVENDOR", "K_USBVID", "K_TYPE", "K_VCC", + "K_VFYLED", "K_NO", "K_YES", "K_TIMEOUT", "K_STABDELAY", "K_CMDEXEDELAY", + "K_HVSPCMDEXEDELAY", "K_SYNCHLOOPS", "K_BYTEDELAY", "K_POLLVALUE", + "K_POLLINDEX", "K_PREDELAY", "K_POSTDELAY", "K_POLLMETHOD", "K_MODE", + "K_DELAY", "K_BLOCKSIZE", "K_READSIZE", "K_HVENTERSTABDELAY", + "K_PROGMODEDELAY", "K_LATCHCYCLES", "K_TOGGLEVTG", "K_POWEROFFDELAY", + "K_RESETDELAYMS", "K_RESETDELAYUS", "K_HVLEAVESTABDELAY", "K_RESETDELAY", + "K_SYNCHCYCLES", "K_HVCMDEXEDELAY", "K_CHIPERASEPULSEWIDTH", + "K_CHIPERASEPOLLTIMEOUT", "K_CHIPERASETIME", "K_PROGRAMFUSEPULSEWIDTH", + "K_PROGRAMFUSEPOLLTIMEOUT", "K_PROGRAMLOCKPULSEWIDTH", + "K_PROGRAMLOCKPOLLTIMEOUT", "K_PP_CONTROLSTACK", "K_HVSP_CONTROLSTACK", + "K_ALLOWFULLPAGEBITSTREAM", "K_ENABLEPAGEPROGRAMMING", "K_HAS_JTAG", + "K_HAS_DW", "K_HAS_PDI", "K_HAS_UPDI", "K_HAS_TPI", "K_IDR", + "K_IS_AT90S1200", "K_IS_AVR32", "K_RAMPZ", "K_SPMCR", "K_EECR", + "K_FLASH_INSTR", "K_EEPROM_INSTR", "TKN_COMMA", "TKN_EQUAL", "TKN_SEMI", + "TKN_TILDE", "TKN_LEFT_PAREN", "TKN_RIGHT_PAREN", "TKN_NUMBER", + "TKN_NUMBER_REAL", "TKN_STRING", "$accept", "number_real", + "configuration", "config", "def", "prog_def", "prog_decl", "part_def", + "part_decl", "string_list", "num_list", "prog_parms", "prog_parm", + "prog_parm_type", "prog_parm_type_id", "prog_parm_conntype", + "prog_parm_conntype_id", "prog_parm_usb", "usb_pid_list", + "pin_number_non_empty", "pin_number", "pin_list_element", + "pin_list_non_empty", "pin_list", "prog_parm_pins", "$@1", "$@2", "$@3", + "$@4", "$@5", "$@6", "$@7", "$@8", "$@9", "$@10", "opcode", "part_parms", + "reset_disposition", "parallel_modes", "retry_lines", "part_parm", + "$@11", "yesno", "mem_specs", "mem_spec", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_int16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393 +}; +# endif + +#define YYPACT_NINF (-264) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-1) + +#define yytable_value_is_error(Yyn) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + -5, -97, -96, -63, -60, -59, 22, 23, 76, -5, + -264, -55, -11, -54, 77, -123, -45, -44, -51, -43, + -41, -33, -264, -264, -264, -52, -20, -19, -18, -14, + -12, -10, -9, -2, -1, 0, 1, 2, 3, 6, + 7, 13, 14, 15, 18, 19, -11, -6, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -3, 20, 21, 24, 25, + 38, 39, 51, 78, 79, 80, 94, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 120, + 122, 123, 125, 126, 127, 129, 130, 131, 132, 133, + 134, 135, 137, 140, 141, 142, 143, 144, 145, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 77, 159, -264, -264, 160, 161, 162, -264, -264, + 163, 164, -264, -264, -16, -264, 5, 16, -264, 70, + -264, -264, -264, -264, -264, -264, 167, 168, 17, 169, + 170, 173, 4, -264, -264, 166, -264, -264, 174, 175, + 176, 177, 180, 181, 182, 183, 184, 186, 187, 188, + 189, -48, -13, -50, -51, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 221, -51, -51, -51, + -51, -51, -51, -51, 222, -51, -51, 223, 224, 225, + 221, 221, 70, 230, -264, -264, -264, -264, -264, -264, + -264, -87, -264, -264, -264, -264, -264, -66, -264, 233, + -66, -66, -66, -66, -66, -66, -264, -264, -264, 234, + -264, -264, -264, -264, -264, -264, -87, -66, -264, 210, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, 229, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, 236, 236, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, 236, + 236, 233, -264, -81, -264, -264, -264, 237, -264, 232, + -264, -264, 231, -264, -264, -264, -264, -264, -264, 235, + -264, -264, 239, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 210, 256, + 257, 258, 221, -264, -87, -264, -264, 259, -51, 260, + 261, 262, 263, -51, 264, 265, 266, 267, 268, 269, + 270, 271, 70, 276, -264, -264, -264, -78, -264, -264, + -264, -264, -264, -264, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, 233, -264, -264 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 4, 0, 0, 0, 0, 0, 19, 16, 0, 5, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 7, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 28, 31, + 30, 29, 9, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 2, 3, 0, 0, 0, 167, 166, + 0, 0, 20, 17, 0, 61, 0, 0, 71, 0, + 69, 67, 75, 73, 63, 65, 0, 0, 0, 0, + 0, 0, 0, 59, 77, 0, 25, 163, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 91, 13, 11, 10, 14, 12, + 33, 58, 38, 39, 40, 37, 32, 52, 21, 27, + 52, 52, 52, 52, 52, 52, 41, 44, 47, 43, + 46, 45, 42, 36, 35, 34, 58, 52, 26, 0, + 113, 111, 100, 101, 102, 103, 104, 99, 156, 157, + 158, 159, 112, 96, 161, 95, 93, 94, 114, 97, + 98, 162, 160, 0, 106, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 142, 135, 136, 137, 138, + 139, 140, 141, 23, 107, 108, 150, 151, 143, 144, + 145, 146, 147, 152, 148, 149, 153, 154, 155, 109, + 110, 165, 92, 0, 49, 53, 55, 57, 62, 0, + 51, 72, 0, 70, 68, 76, 74, 64, 66, 0, + 60, 78, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, + 0, 0, 0, 50, 0, 22, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 168, 105, 24, 0, 56, 172, + 170, 176, 175, 173, 174, 177, 178, 179, 171, 184, + 180, 181, 182, 183, 185, 169, 54 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -264, -264, -264, -264, 281, -264, -264, -264, -264, -231, + -214, -264, 90, -264, -264, -264, -264, -264, -264, -237, + -151, -85, -264, 34, -264, -264, -264, -264, -264, -264, + -264, -264, -264, -264, -264, -263, -264, -264, -264, -264, + 278, -264, -181, -264, -65 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 135, 8, 9, 10, 11, 12, 13, 14, 249, + 324, 46, 47, 48, 265, 49, 245, 50, 259, 350, + 351, 346, 347, 348, 51, 266, 241, 254, 255, 251, + 250, 247, 253, 252, 267, 130, 131, 288, 284, 291, + 132, 269, 140, 378, 379 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 285, 341, 325, 292, 345, 263, 377, 25, 283, 26, + 286, 27, 289, 133, 134, 290, 339, 340, 28, 1, + 2, 3, 4, 5, 29, 287, 30, 138, 139, 345, + 138, 139, 31, 32, 15, 16, 326, 327, 328, 329, + 330, 331, 332, 33, 334, 335, 343, 34, 6, 344, + 7, 35, 381, 382, 36, 383, 242, 426, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 349, 17, 243, + 344, 18, 19, 244, 20, 21, 22, 24, 52, 144, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 136, 137, 141, 66, 142, 67, 353, + 354, 355, 356, 357, 358, 143, 68, 69, 70, 71, + 72, 145, 146, 147, 73, 377, 361, 148, 74, 149, + 240, 150, 151, 75, 76, 77, 166, 78, 79, 152, + 153, 154, 155, 156, 157, 167, 165, 158, 159, 80, + 81, 82, 264, 83, 160, 161, 162, 345, 84, 163, + 164, 168, 169, 258, 246, 170, 171, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 407, 172, + 173, 424, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 174, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 410, 248, 175, + 176, 177, 415, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 178, 362, 363, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 364, 201, 365, 202, 203, 366, 204, 205, 206, 367, + 207, 208, 209, 210, 211, 212, 213, 368, 214, 369, + 370, 215, 216, 217, 218, 219, 220, 371, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 23, 234, 235, 236, 237, 238, 239, 372, 268, 408, + 360, 373, 374, 375, 376, 256, 257, 260, 261, 262, + 270, 271, 0, 403, 272, 273, 274, 275, 276, 0, + 278, 277, 279, 280, 281, 282, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 0, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 333, 336, + 337, 338, 342, 352, 359, 380, 381, 384, 383, 385, + 387, 386, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 0, 404, 0, + 0, 0, 0, 405, 406, 409, 411, 412, 413, 414, + 416, 417, 418, 419, 420, 421, 422, 423, 425, 233 +}; + +static const yytype_int16 yycheck[] = +{ + 181, 232, 216, 184, 241, 1, 269, 18, 56, 20, + 23, 22, 62, 136, 137, 65, 230, 231, 29, 24, + 25, 26, 27, 28, 35, 38, 37, 78, 79, 266, + 78, 79, 43, 44, 131, 131, 217, 218, 219, 220, + 221, 222, 223, 54, 225, 226, 133, 58, 53, 136, + 55, 62, 130, 134, 65, 136, 51, 135, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 133, 131, 64, + 136, 131, 131, 68, 52, 52, 0, 132, 132, 131, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 138, 138, 138, 19, 138, 21, 250, + 251, 252, 253, 254, 255, 138, 29, 30, 31, 32, + 33, 131, 131, 131, 37, 378, 267, 131, 41, 131, + 136, 131, 131, 46, 47, 48, 132, 50, 51, 131, + 131, 131, 131, 131, 131, 138, 46, 131, 131, 62, + 63, 64, 138, 66, 131, 131, 131, 384, 71, 131, + 131, 131, 131, 136, 138, 131, 131, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 382, 131, + 131, 402, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 131, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 388, 138, 131, + 131, 131, 393, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 131, 16, 17, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 40, 131, 42, 131, 131, 45, 131, 131, 131, 49, + 131, 131, 131, 131, 131, 131, 131, 57, 131, 59, + 60, 131, 131, 131, 131, 131, 131, 67, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 9, 132, 132, 132, 132, 132, 132, 87, 132, 384, + 266, 91, 92, 93, 94, 138, 138, 138, 138, 136, + 136, 136, -1, 378, 138, 138, 136, 136, 136, -1, + 136, 138, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, -1, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 132, 130, 130, 136, 130, 130, 136, 138, + 131, 136, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, -1, 132, -1, + -1, -1, -1, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 132, 131 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 24, 25, 26, 27, 28, 53, 55, 141, 142, + 143, 144, 145, 146, 147, 131, 131, 131, 131, 131, + 52, 52, 0, 143, 132, 18, 20, 22, 29, 35, + 37, 43, 44, 54, 58, 62, 65, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 150, 151, 152, 154, + 156, 163, 132, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 19, 21, 29, 30, + 31, 32, 33, 37, 41, 46, 47, 48, 50, 51, + 62, 63, 64, 66, 71, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 174, 175, 179, 136, 137, 140, 138, 138, 78, 79, + 181, 138, 138, 138, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 151, 132, 138, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 179, 132, 132, 132, 132, 132, 132, + 136, 165, 51, 64, 68, 155, 138, 170, 138, 148, + 169, 168, 172, 171, 166, 167, 138, 138, 136, 157, + 138, 138, 136, 1, 138, 153, 164, 173, 132, 180, + 136, 136, 138, 138, 136, 136, 136, 138, 136, 136, + 136, 136, 136, 56, 177, 181, 23, 38, 176, 62, + 65, 178, 181, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 149, 149, 181, 181, 181, 181, + 181, 181, 181, 136, 181, 181, 136, 136, 136, 149, + 149, 148, 132, 133, 136, 158, 160, 161, 162, 133, + 158, 159, 130, 159, 159, 159, 159, 159, 159, 130, + 162, 159, 16, 17, 40, 42, 45, 49, 57, 59, + 60, 67, 87, 91, 92, 93, 94, 174, 182, 183, + 136, 130, 134, 136, 130, 138, 136, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 183, 132, 136, 136, 149, 160, 136, + 181, 136, 136, 136, 136, 181, 136, 136, 136, 136, + 136, 136, 136, 136, 148, 132, 135 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 139, 140, 140, 141, 141, 142, 142, 143, 143, + 143, 143, 143, 143, 143, 144, 145, 145, 146, 147, + 147, 148, 148, 149, 149, 150, 150, 151, 151, 151, + 151, 151, 151, 151, 152, 153, 153, 154, 155, 155, + 155, 156, 156, 156, 156, 156, 156, 157, 157, 158, + 158, 159, 159, 160, 160, 161, 161, 162, 162, 164, + 163, 165, 163, 166, 163, 167, 163, 168, 163, 169, + 163, 170, 163, 171, 163, 172, 163, 173, 163, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 175, 175, 176, 176, 177, 177, 178, 178, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 180, 179, 179, 181, 181, 182, 182, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 1, 1, 0, 1, 1, 2, 2, 2, + 4, 4, 4, 4, 4, 2, 1, 3, 2, 1, + 3, 1, 3, 1, 3, 2, 3, 3, 1, 1, + 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 1, 3, 1, + 2, 1, 0, 1, 4, 1, 3, 1, 0, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 0, 4, 3, 1, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[+yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else +/* Return the length of YYSTR. */ +static YYPTRDIFF_T +yystrlen (const char *yystr) +{ + YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYPTRDIFF_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYPTRDIFF_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (yyres) + return yystpcpy (yyres, yystr) - yyres; + else + return yystrlen (yystr); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + yy_state_t *yyssp, int yytoken) +{ + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Actual size of YYARG. */ + int yycount = 0; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[+*yyssp]; + YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + yysize = yysize0; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + /* Don't count the "%s"s in the final size, but reserve room for + the terminator. */ + YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + ++yyp; + ++yyformat; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss; + yy_state_t *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYPTRDIFF_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 214 "config_gram.y" + { + yyval = yyvsp[0]; + /* convert value to real */ + yyval->value.number_real = yyval->value.number; + yyval->value.type = V_NUM_REAL; + } +#line 1926 "config_gram.c" + break; + + case 3: +#line 220 "config_gram.y" + { + yyval = yyvsp[0]; + } +#line 1934 "config_gram.c" + break; + + case 10: +#line 239 "config_gram.y" + { + strncpy(default_programmer, yyvsp[-1]->value.string, MAX_STR_CONST); + default_programmer[MAX_STR_CONST-1] = 0; + free_token(yyvsp[-1]); + } +#line 1944 "config_gram.c" + break; + + case 11: +#line 245 "config_gram.y" + { + strncpy(default_parallel, yyvsp[-1]->value.string, PATH_MAX); + default_parallel[PATH_MAX-1] = 0; + free_token(yyvsp[-1]); + } +#line 1954 "config_gram.c" + break; + + case 12: +#line 251 "config_gram.y" + { + strncpy(default_serial, yyvsp[-1]->value.string, PATH_MAX); + default_serial[PATH_MAX-1] = 0; + free_token(yyvsp[-1]); + } +#line 1964 "config_gram.c" + break; + + case 13: +#line 257 "config_gram.y" + { + default_bitclock = yyvsp[-1]->value.number_real; + free_token(yyvsp[-1]); + } +#line 1973 "config_gram.c" + break; + + case 14: +#line 262 "config_gram.y" + { + if (yyvsp[-1]->primary == K_YES) + default_safemode = 1; + else if (yyvsp[-1]->primary == K_NO) + default_safemode = 0; + free_token(yyvsp[-1]); + } +#line 1985 "config_gram.c" + break; + + case 15: +#line 274 "config_gram.y" + { + PROGRAMMER * existing_prog; + char * id; + if (lsize(current_prog->id) == 0) { + yyerror("required parameter id not specified"); + YYABORT; + } + if (current_prog->initpgm == NULL) { + yyerror("programmer type not specified"); + YYABORT; + } + id = ldata(lfirst(current_prog->id)); + existing_prog = locate_programmer(programmers, id); + if (existing_prog) { + { /* temporarly set lineno to lineno of programmer start */ + int temp = lineno; lineno = current_prog->lineno; + yywarning("programmer %s overwrites previous definition %s:%d.", + id, existing_prog->config_file, existing_prog->lineno); + lineno = temp; + } + lrmv_d(programmers, existing_prog); + pgm_free(existing_prog); + } + PUSH(programmers, current_prog); +// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed +// pgm_display_generic(current_prog, id); + current_prog = NULL; + } +#line 2018 "config_gram.c" + break; + + case 16: +#line 307 "config_gram.y" + { current_prog = pgm_new(); + if (current_prog == NULL) { + yyerror("could not create pgm instance"); + YYABORT; + } + strcpy(current_prog->config_file, infile); + current_prog->lineno = lineno; + } +#line 2031 "config_gram.c" + break; + + case 17: +#line 317 "config_gram.y" + { + struct programmer_t * pgm = locate_programmer(programmers, yyvsp[0]->value.string); + if (pgm == NULL) { + yyerror("parent programmer %s not found", yyvsp[0]->value.string); + free_token(yyvsp[0]); + YYABORT; + } + current_prog = pgm_dup(pgm); + if (current_prog == NULL) { + yyerror("could not duplicate pgm instance"); + free_token(yyvsp[0]); + YYABORT; + } + strcpy(current_prog->config_file, infile); + current_prog->lineno = lineno; + free_token(yyvsp[0]); + } +#line 2053 "config_gram.c" + break; + + case 18: +#line 339 "config_gram.y" + { + LNODEID ln; + AVRMEM * m; + AVRPART * existing_part; + + if (current_part->id[0] == 0) { + yyerror("required parameter id not specified"); + YYABORT; + } + + /* + * perform some sanity checking, and compute the number of bits + * to shift a page for constructing the page address for + * page-addressed memories. + */ + for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) { + m = ldata(ln); + if (m->paged) { + if (m->page_size == 0) { + yyerror("must specify page_size for paged memory"); + YYABORT; + } + if (m->num_pages == 0) { + yyerror("must specify num_pages for paged memory"); + YYABORT; + } + if (m->size != m->page_size * m->num_pages) { + yyerror("page size (%u) * num_pages (%u) = " + "%u does not match memory size (%u)", + m->page_size, + m->num_pages, + m->page_size * m->num_pages, + m->size); + YYABORT; + } + + } + } + + existing_part = locate_part(part_list, current_part->id); + if (existing_part) { + { /* temporarly set lineno to lineno of part start */ + int temp = lineno; lineno = current_part->lineno; + yywarning("part %s overwrites previous definition %s:%d.", + current_part->id, + existing_part->config_file, existing_part->lineno); + lineno = temp; + } + lrmv_d(part_list, existing_part); + avr_free_part(existing_part); + } + PUSH(part_list, current_part); + current_part = NULL; + } +#line 2112 "config_gram.c" + break; + + case 19: +#line 397 "config_gram.y" + { + current_part = avr_new_part(); + if (current_part == NULL) { + yyerror("could not create part instance"); + YYABORT; + } + strcpy(current_part->config_file, infile); + current_part->lineno = lineno; + } +#line 2126 "config_gram.c" + break; + + case 20: +#line 407 "config_gram.y" + { + AVRPART * parent_part = locate_part(part_list, yyvsp[0]->value.string); + if (parent_part == NULL) { + yyerror("can't find parent part"); + free_token(yyvsp[0]); + YYABORT; + } + + current_part = avr_dup_part(parent_part); + if (current_part == NULL) { + yyerror("could not duplicate part instance"); + free_token(yyvsp[0]); + YYABORT; + } + strcpy(current_part->config_file, infile); + current_part->lineno = lineno; + + free_token(yyvsp[0]); + } +#line 2150 "config_gram.c" + break; + + case 21: +#line 429 "config_gram.y" + { ladd(string_list, yyvsp[0]); } +#line 2156 "config_gram.c" + break; + + case 22: +#line 430 "config_gram.y" + { ladd(string_list, yyvsp[0]); } +#line 2162 "config_gram.c" + break; + + case 23: +#line 435 "config_gram.y" + { ladd(number_list, yyvsp[0]); } +#line 2168 "config_gram.c" + break; + + case 24: +#line 436 "config_gram.y" + { ladd(number_list, yyvsp[0]); } +#line 2174 "config_gram.c" + break; + + case 27: +#line 445 "config_gram.y" + { + { + TOKEN * t; + char *s; + int do_yyabort = 0; + while (lsize(string_list)) { + t = lrmv_n(string_list, 1); + if (!do_yyabort) { + s = dup_string(t->value.string); + if (s == NULL) { + do_yyabort = 1; + } else { + ladd(current_prog->id, s); + } + } + /* if do_yyabort == 1 just make the list empty */ + free_token(t); + } + if (do_yyabort) { + YYABORT; + } + } + } +#line 2202 "config_gram.c" + break; + + case 32: +#line 476 "config_gram.y" + { + strncpy(current_prog->desc, yyvsp[0]->value.string, PGM_DESCLEN); + current_prog->desc[PGM_DESCLEN-1] = 0; + free_token(yyvsp[0]); + } +#line 2212 "config_gram.c" + break; + + case 33: +#line 481 "config_gram.y" + { + { + current_prog->baudrate = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } + } +#line 2223 "config_gram.c" + break; + + case 35: +#line 494 "config_gram.y" + { + const struct programmer_type_t * pgm_type = locate_programmer_type(yyvsp[0]->value.string); + if (pgm_type == NULL) { + yyerror("programmer type %s not found", yyvsp[0]->value.string); + free_token(yyvsp[0]); + YYABORT; + } + current_prog->initpgm = pgm_type->initpgm; + free_token(yyvsp[0]); +} +#line 2238 "config_gram.c" + break; + + case 36: +#line 505 "config_gram.y" +{ + yyerror("programmer type must be written as \"id_type\""); + YYABORT; +} +#line 2247 "config_gram.c" + break; + + case 38: +#line 516 "config_gram.y" + { current_prog->conntype = CONNTYPE_PARALLEL; } +#line 2253 "config_gram.c" + break; + + case 39: +#line 517 "config_gram.y" + { current_prog->conntype = CONNTYPE_SERIAL; } +#line 2259 "config_gram.c" + break; + + case 40: +#line 518 "config_gram.y" + { current_prog->conntype = CONNTYPE_USB; } +#line 2265 "config_gram.c" + break; + + case 41: +#line 522 "config_gram.y" + { + { + strncpy(current_prog->usbdev, yyvsp[0]->value.string, PGM_USBSTRINGLEN); + current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0; + free_token(yyvsp[0]); + } + } +#line 2277 "config_gram.c" + break; + + case 42: +#line 529 "config_gram.y" + { + { + current_prog->usbvid = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } + } +#line 2288 "config_gram.c" + break; + + case 44: +#line 536 "config_gram.y" + { + { + strncpy(current_prog->usbsn, yyvsp[0]->value.string, PGM_USBSTRINGLEN); + current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0; + free_token(yyvsp[0]); + } + } +#line 2300 "config_gram.c" + break; + + case 45: +#line 543 "config_gram.y" + { + { + strncpy(current_prog->usbvendor, yyvsp[0]->value.string, PGM_USBSTRINGLEN); + current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0; + free_token(yyvsp[0]); + } + } +#line 2312 "config_gram.c" + break; + + case 46: +#line 550 "config_gram.y" + { + { + strncpy(current_prog->usbproduct, yyvsp[0]->value.string, PGM_USBSTRINGLEN); + current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0; + free_token(yyvsp[0]); + } + } +#line 2324 "config_gram.c" + break; + + case 47: +#line 560 "config_gram.y" + { + { + /* overwrite pids, so clear the existing entries */ + ldestroy_cb(current_prog->usbpid, free); + current_prog->usbpid = lcreat(NULL, 0); + } + { + int *ip = malloc(sizeof(int)); + if (ip) { + *ip = yyvsp[0]->value.number; + ladd(current_prog->usbpid, ip); + } + free_token(yyvsp[0]); + } + } +#line 2344 "config_gram.c" + break; + + case 48: +#line 575 "config_gram.y" + { + { + int *ip = malloc(sizeof(int)); + if (ip) { + *ip = yyvsp[0]->value.number; + ladd(current_prog->usbpid, ip); + } + free_token(yyvsp[0]); + } + } +#line 2359 "config_gram.c" + break; + + case 49: +#line 588 "config_gram.y" + { if(0 != assign_pin(pin_name, yyvsp[0], 0)) YYABORT; } +#line 2365 "config_gram.c" + break; + + case 50: +#line 590 "config_gram.y" + { if(0 != assign_pin(pin_name, yyvsp[0], 1)) YYABORT; } +#line 2371 "config_gram.c" + break; + + case 52: +#line 596 "config_gram.y" + { pin_clear_all(&(current_prog->pin[pin_name])); } +#line 2377 "config_gram.c" + break; + + case 54: +#line 602 "config_gram.y" + { if(0 != assign_pin_list(1)) YYABORT; } +#line 2383 "config_gram.c" + break; + + case 58: +#line 615 "config_gram.y" + { pin_clear_all(&(current_prog->pin[pin_name])); } +#line 2389 "config_gram.c" + break; + + case 59: +#line 619 "config_gram.y" + {pin_name = PPI_AVR_VCC; } +#line 2395 "config_gram.c" + break; + + case 61: +#line 620 "config_gram.y" + {pin_name = PPI_AVR_BUFF; } +#line 2401 "config_gram.c" + break; + + case 63: +#line 621 "config_gram.y" + {pin_name = PIN_AVR_RESET;} +#line 2407 "config_gram.c" + break; + + case 64: +#line 621 "config_gram.y" + { free_token(yyvsp[-3]); } +#line 2413 "config_gram.c" + break; + + case 65: +#line 622 "config_gram.y" + {pin_name = PIN_AVR_SCK; } +#line 2419 "config_gram.c" + break; + + case 66: +#line 622 "config_gram.y" + { free_token(yyvsp[-3]); } +#line 2425 "config_gram.c" + break; + + case 67: +#line 623 "config_gram.y" + {pin_name = PIN_AVR_MOSI; } +#line 2431 "config_gram.c" + break; + + case 69: +#line 624 "config_gram.y" + {pin_name = PIN_AVR_MISO; } +#line 2437 "config_gram.c" + break; + + case 71: +#line 625 "config_gram.y" + {pin_name = PIN_LED_ERR; } +#line 2443 "config_gram.c" + break; + + case 73: +#line 626 "config_gram.y" + {pin_name = PIN_LED_RDY; } +#line 2449 "config_gram.c" + break; + + case 75: +#line 627 "config_gram.y" + {pin_name = PIN_LED_PGM; } +#line 2455 "config_gram.c" + break; + + case 77: +#line 628 "config_gram.y" + {pin_name = PIN_LED_VFY; } +#line 2461 "config_gram.c" + break; + + case 99: +#line 667 "config_gram.y" + { + strncpy(current_part->id, yyvsp[0]->value.string, AVR_IDLEN); + current_part->id[AVR_IDLEN-1] = 0; + free_token(yyvsp[0]); + } +#line 2471 "config_gram.c" + break; + + case 100: +#line 674 "config_gram.y" + { + strncpy(current_part->desc, yyvsp[0]->value.string, AVR_DESCLEN); + current_part->desc[AVR_DESCLEN-1] = 0; + free_token(yyvsp[0]); + } +#line 2481 "config_gram.c" + break; + + case 101: +#line 681 "config_gram.y" + { + strncpy(current_part->family_id, yyvsp[0]->value.string, AVR_FAMILYIDLEN); + current_part->family_id[AVR_FAMILYIDLEN] = 0; + free_token(yyvsp[0]); + } +#line 2491 "config_gram.c" + break; + + case 102: +#line 687 "config_gram.y" + { + { + yyerror("devicecode is deprecated, use " + "stk500_devcode instead"); + YYABORT; + } + } +#line 2503 "config_gram.c" + break; + + case 103: +#line 695 "config_gram.y" + { + { + current_part->stk500_devcode = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } + } +#line 2514 "config_gram.c" + break; + + case 104: +#line 702 "config_gram.y" + { + { + current_part->avr910_devcode = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } + } +#line 2525 "config_gram.c" + break; + + case 105: +#line 709 "config_gram.y" + { + { + current_part->signature[0] = yyvsp[-2]->value.number; + current_part->signature[1] = yyvsp[-1]->value.number; + current_part->signature[2] = yyvsp[0]->value.number; + free_token(yyvsp[-2]); + free_token(yyvsp[-1]); + free_token(yyvsp[0]); + } + } +#line 2540 "config_gram.c" + break; + + case 106: +#line 720 "config_gram.y" + { + { + current_part->usbpid = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } + } +#line 2551 "config_gram.c" + break; + + case 107: +#line 727 "config_gram.y" + { + { + TOKEN * t; + unsigned nbytes; + int ok; + + current_part->ctl_stack_type = CTL_STACK_PP; + nbytes = 0; + ok = 1; + + memset(current_part->controlstack, 0, CTL_STACK_SIZE); + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (nbytes < CTL_STACK_SIZE) + { + current_part->controlstack[nbytes] = t->value.number; + nbytes++; + } + else + { + ok = 0; + } + free_token(t); + } + if (!ok) + { + yywarning("too many bytes in control stack"); + } + } + } +#line 2586 "config_gram.c" + break; + + case 108: +#line 758 "config_gram.y" + { + { + TOKEN * t; + unsigned nbytes; + int ok; + + current_part->ctl_stack_type = CTL_STACK_HVSP; + nbytes = 0; + ok = 1; + + memset(current_part->controlstack, 0, CTL_STACK_SIZE); + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (nbytes < CTL_STACK_SIZE) + { + current_part->controlstack[nbytes] = t->value.number; + nbytes++; + } + else + { + ok = 0; + } + free_token(t); + } + if (!ok) + { + yywarning("too many bytes in control stack"); + } + } + } +#line 2621 "config_gram.c" + break; + + case 109: +#line 789 "config_gram.y" + { + { + TOKEN * t; + unsigned nbytes; + int ok; + + nbytes = 0; + ok = 1; + + memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE); + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (nbytes < FLASH_INSTR_SIZE) + { + current_part->flash_instr[nbytes] = t->value.number; + nbytes++; + } + else + { + ok = 0; + } + free_token(t); + } + if (!ok) + { + yywarning("too many bytes in flash instructions"); + } + } + } +#line 2655 "config_gram.c" + break; + + case 110: +#line 819 "config_gram.y" + { + { + TOKEN * t; + unsigned nbytes; + int ok; + + nbytes = 0; + ok = 1; + + memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE); + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (nbytes < EEPROM_INSTR_SIZE) + { + current_part->eeprom_instr[nbytes] = t->value.number; + nbytes++; + } + else + { + ok = 0; + } + free_token(t); + } + if (!ok) + { + yywarning("too many bytes in EEPROM instructions"); + } + } + } +#line 2689 "config_gram.c" + break; + + case 111: +#line 850 "config_gram.y" + { + current_part->chip_erase_delay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2698 "config_gram.c" + break; + + case 112: +#line 856 "config_gram.y" + { + current_part->pagel = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2707 "config_gram.c" + break; + + case 113: +#line 862 "config_gram.y" + { + current_part->bs2 = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2716 "config_gram.c" + break; + + case 114: +#line 868 "config_gram.y" + { + if (yyvsp[0]->primary == K_DEDICATED) + current_part->reset_disposition = RESET_DEDICATED; + else if (yyvsp[0]->primary == K_IO) + current_part->reset_disposition = RESET_IO; + + free_tokens(2, yyvsp[-2], yyvsp[0]); + } +#line 2729 "config_gram.c" + break; + + case 115: +#line 878 "config_gram.y" + { + current_part->timeout = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2738 "config_gram.c" + break; + + case 116: +#line 884 "config_gram.y" + { + current_part->stabdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2747 "config_gram.c" + break; + + case 117: +#line 890 "config_gram.y" + { + current_part->cmdexedelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2756 "config_gram.c" + break; + + case 118: +#line 896 "config_gram.y" + { + current_part->hvspcmdexedelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2765 "config_gram.c" + break; + + case 119: +#line 902 "config_gram.y" + { + current_part->synchloops = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2774 "config_gram.c" + break; + + case 120: +#line 908 "config_gram.y" + { + current_part->bytedelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2783 "config_gram.c" + break; + + case 121: +#line 914 "config_gram.y" + { + current_part->pollvalue = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2792 "config_gram.c" + break; + + case 122: +#line 920 "config_gram.y" + { + current_part->pollindex = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2801 "config_gram.c" + break; + + case 123: +#line 926 "config_gram.y" + { + current_part->predelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2810 "config_gram.c" + break; + + case 124: +#line 932 "config_gram.y" + { + current_part->postdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2819 "config_gram.c" + break; + + case 125: +#line 938 "config_gram.y" + { + current_part->pollmethod = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2828 "config_gram.c" + break; + + case 126: +#line 944 "config_gram.y" + { + current_part->hventerstabdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2837 "config_gram.c" + break; + + case 127: +#line 950 "config_gram.y" + { + current_part->progmodedelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2846 "config_gram.c" + break; + + case 128: +#line 956 "config_gram.y" + { + current_part->latchcycles = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2855 "config_gram.c" + break; + + case 129: +#line 962 "config_gram.y" + { + current_part->togglevtg = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2864 "config_gram.c" + break; + + case 130: +#line 968 "config_gram.y" + { + current_part->poweroffdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2873 "config_gram.c" + break; + + case 131: +#line 974 "config_gram.y" + { + current_part->resetdelayms = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2882 "config_gram.c" + break; + + case 132: +#line 980 "config_gram.y" + { + current_part->resetdelayus = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2891 "config_gram.c" + break; + + case 133: +#line 986 "config_gram.y" + { + current_part->hvleavestabdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2900 "config_gram.c" + break; + + case 134: +#line 992 "config_gram.y" + { + current_part->resetdelay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2909 "config_gram.c" + break; + + case 135: +#line 998 "config_gram.y" + { + current_part->chiperasepulsewidth = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2918 "config_gram.c" + break; + + case 136: +#line 1004 "config_gram.y" + { + current_part->chiperasepolltimeout = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2927 "config_gram.c" + break; + + case 137: +#line 1010 "config_gram.y" + { + current_part->chiperasetime = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2936 "config_gram.c" + break; + + case 138: +#line 1016 "config_gram.y" + { + current_part->programfusepulsewidth = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2945 "config_gram.c" + break; + + case 139: +#line 1022 "config_gram.y" + { + current_part->programfusepolltimeout = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2954 "config_gram.c" + break; + + case 140: +#line 1028 "config_gram.y" + { + current_part->programlockpulsewidth = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2963 "config_gram.c" + break; + + case 141: +#line 1034 "config_gram.y" + { + current_part->programlockpolltimeout = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2972 "config_gram.c" + break; + + case 142: +#line 1040 "config_gram.y" + { + current_part->synchcycles = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 2981 "config_gram.c" + break; + + case 143: +#line 1046 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_HAS_JTAG; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_HAS_JTAG; + + free_token(yyvsp[0]); + } +#line 2994 "config_gram.c" + break; + + case 144: +#line 1056 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_HAS_DW; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_HAS_DW; + + free_token(yyvsp[0]); + } +#line 3007 "config_gram.c" + break; + + case 145: +#line 1066 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_HAS_PDI; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_HAS_PDI; + + free_token(yyvsp[0]); + } +#line 3020 "config_gram.c" + break; + + case 146: +#line 1076 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_HAS_UPDI; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_HAS_UPDI; + + free_token(yyvsp[0]); + } +#line 3033 "config_gram.c" + break; + + case 147: +#line 1086 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_HAS_TPI; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_HAS_TPI; + + free_token(yyvsp[0]); + } +#line 3046 "config_gram.c" + break; + + case 148: +#line 1096 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_IS_AT90S1200; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_IS_AT90S1200; + + free_token(yyvsp[0]); + } +#line 3059 "config_gram.c" + break; + + case 149: +#line 1106 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_AVR32; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_AVR32; + + free_token(yyvsp[0]); + } +#line 3072 "config_gram.c" + break; + + case 150: +#line 1116 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM; + + free_token(yyvsp[0]); + } +#line 3085 "config_gram.c" + break; + + case 151: +#line 1126 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING; + + free_token(yyvsp[0]); + } +#line 3098 "config_gram.c" + break; + + case 152: +#line 1136 "config_gram.y" + { + current_part->idr = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3107 "config_gram.c" + break; + + case 153: +#line 1142 "config_gram.y" + { + current_part->rampz = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3116 "config_gram.c" + break; + + case 154: +#line 1148 "config_gram.y" + { + current_part->spmcr = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3125 "config_gram.c" + break; + + case 155: +#line 1154 "config_gram.y" + { + current_part->eecr = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3134 "config_gram.c" + break; + + case 156: +#line 1160 "config_gram.y" + { + current_part->mcu_base = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3143 "config_gram.c" + break; + + case 157: +#line 1166 "config_gram.y" + { + current_part->nvm_base = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3152 "config_gram.c" + break; + + case 158: +#line 1172 "config_gram.y" + { + current_part->ocd_base = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3161 "config_gram.c" + break; + + case 159: +#line 1178 "config_gram.y" + { + current_part->ocdrev = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3170 "config_gram.c" + break; + + case 160: +#line 1184 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) + current_part->flags |= AVRPART_SERIALOK; + else if (yyvsp[0]->primary == K_NO) + current_part->flags &= ~AVRPART_SERIALOK; + + free_token(yyvsp[0]); + } +#line 3183 "config_gram.c" + break; + + case 161: +#line 1194 "config_gram.y" + { + if (yyvsp[0]->primary == K_YES) { + current_part->flags |= AVRPART_PARALLELOK; + current_part->flags &= ~AVRPART_PSEUDOPARALLEL; + } + else if (yyvsp[0]->primary == K_NO) { + current_part->flags &= ~AVRPART_PARALLELOK; + current_part->flags &= ~AVRPART_PSEUDOPARALLEL; + } + else if (yyvsp[0]->primary == K_PSEUDO) { + current_part->flags |= AVRPART_PARALLELOK; + current_part->flags |= AVRPART_PSEUDOPARALLEL; + } + + + free_token(yyvsp[0]); + } +#line 3205 "config_gram.c" + break; + + case 162: +#line 1213 "config_gram.y" + { + switch (yyvsp[0]->primary) { + case K_RESET : + current_part->retry_pulse = PIN_AVR_RESET; + break; + case K_SCK : + current_part->retry_pulse = PIN_AVR_SCK; + break; + } + + free_token(yyvsp[-2]); + } +#line 3222 "config_gram.c" + break; + + case 163: +#line 1236 "config_gram.y" + { + current_mem = avr_new_memtype(); + if (current_mem == NULL) { + yyerror("could not create mem instance"); + free_token(yyvsp[0]); + YYABORT; + } + strncpy(current_mem->desc, yyvsp[0]->value.string, AVR_MEMDESCLEN); + current_mem->desc[AVR_MEMDESCLEN-1] = 0; + free_token(yyvsp[0]); + } +#line 3238 "config_gram.c" + break; + + case 164: +#line 1248 "config_gram.y" + { + AVRMEM * existing_mem; + + existing_mem = avr_locate_mem(current_part, current_mem->desc); + if (existing_mem != NULL) { + lrmv_d(current_part->mem, existing_mem); + avr_free_mem(existing_mem); + } + ladd(current_part->mem, current_mem); + current_mem = NULL; + } +#line 3254 "config_gram.c" + break; + + case 165: +#line 1260 "config_gram.y" + { + { + int opnum; + OPCODE * op; + + opnum = which_opcode(yyvsp[-2]); + if (opnum < 0) YYABORT; + op = avr_new_opcode(); + if (op == NULL) { + yyerror("could not create opcode instance"); + free_token(yyvsp[-2]); + YYABORT; + } + if(0 != parse_cmdbits(op)) YYABORT; + if (current_part->op[opnum] != NULL) { + /*yywarning("operation redefined");*/ + avr_free_opcode(current_part->op[opnum]); + } + current_part->op[opnum] = op; + + free_token(yyvsp[-2]); + } + } +#line 3282 "config_gram.c" + break; + + case 170: +#line 1299 "config_gram.y" + { + current_mem->paged = yyvsp[0]->primary == K_YES ? 1 : 0; + free_token(yyvsp[0]); + } +#line 3291 "config_gram.c" + break; + + case 171: +#line 1305 "config_gram.y" + { + current_mem->size = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3300 "config_gram.c" + break; + + case 172: +#line 1312 "config_gram.y" + { + current_mem->page_size = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3309 "config_gram.c" + break; + + case 173: +#line 1318 "config_gram.y" + { + current_mem->num_pages = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3318 "config_gram.c" + break; + + case 174: +#line 1324 "config_gram.y" + { + current_mem->offset = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3327 "config_gram.c" + break; + + case 175: +#line 1330 "config_gram.y" + { + current_mem->min_write_delay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3336 "config_gram.c" + break; + + case 176: +#line 1336 "config_gram.y" + { + current_mem->max_write_delay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3345 "config_gram.c" + break; + + case 177: +#line 1342 "config_gram.y" + { + current_mem->pwroff_after_write = yyvsp[0]->primary == K_YES ? 1 : 0; + free_token(yyvsp[0]); + } +#line 3354 "config_gram.c" + break; + + case 178: +#line 1348 "config_gram.y" + { + current_mem->readback[0] = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3363 "config_gram.c" + break; + + case 179: +#line 1354 "config_gram.y" + { + current_mem->readback[1] = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3372 "config_gram.c" + break; + + case 180: +#line 1361 "config_gram.y" + { + current_mem->mode = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3381 "config_gram.c" + break; + + case 181: +#line 1367 "config_gram.y" + { + current_mem->delay = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3390 "config_gram.c" + break; + + case 182: +#line 1373 "config_gram.y" + { + current_mem->blocksize = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3399 "config_gram.c" + break; + + case 183: +#line 1379 "config_gram.y" + { + current_mem->readsize = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3408 "config_gram.c" + break; + + case 184: +#line 1385 "config_gram.y" + { + current_mem->pollindex = yyvsp[0]->value.number; + free_token(yyvsp[0]); + } +#line 3417 "config_gram.c" + break; + + case 185: +#line 1391 "config_gram.y" + { + { + int opnum; + OPCODE * op; + + opnum = which_opcode(yyvsp[-2]); + if (opnum < 0) YYABORT; + op = avr_new_opcode(); + if (op == NULL) { + yyerror("could not create opcode instance"); + free_token(yyvsp[-2]); + YYABORT; + } + if(0 != parse_cmdbits(op)) YYABORT; + if (current_mem->op[opnum] != NULL) { + /*yywarning("operation redefined");*/ + avr_free_opcode(current_mem->op[opnum]); + } + current_mem->op[opnum] = op; + + free_token(yyvsp[-2]); + } + } +#line 3445 "config_gram.c" + break; + + +#line 3449 "config_gram.c" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[+*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 1417 "config_gram.y" + + +#if 0 +static char * vtypestr(int type) +{ + switch (type) { + case V_NUM : return "INTEGER"; + case V_NUM_REAL: return "REAL"; + case V_STR : return "STRING"; + default: + return ""; + } +} +#endif + + +static int assign_pin(int pinno, TOKEN * v, int invert) +{ + int value; + + value = v->value.number; + free_token(v); + + if ((value < PIN_MIN) || (value > PIN_MAX)) { + yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX)); + return -1; + } + + pin_set_value(&(current_prog->pin[pinno]), value, invert); + + return 0; +} + +static int assign_pin_list(int invert) +{ + TOKEN * t; + int pin; + int rv = 0; + + current_prog->pinno[pin_name] = 0; + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (rv == 0) { + pin = t->value.number; + if ((pin < PIN_MIN) || (pin > PIN_MAX)) { + yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX)); + rv = -1; + /* loop clears list and frees tokens */ + } + pin_set_value(&(current_prog->pin[pin_name]), pin, invert); + } + free_token(t); + } + return rv; +} + +static int which_opcode(TOKEN * opcode) +{ + switch (opcode->primary) { + case K_READ : return AVR_OP_READ; break; + case K_WRITE : return AVR_OP_WRITE; break; + case K_READ_LO : return AVR_OP_READ_LO; break; + case K_READ_HI : return AVR_OP_READ_HI; break; + case K_WRITE_LO : return AVR_OP_WRITE_LO; break; + case K_WRITE_HI : return AVR_OP_WRITE_HI; break; + case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break; + case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break; + case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break; + case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break; + case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break; + case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break; + default : + yyerror("invalid opcode"); + return -1; + break; + } +} + + +static int parse_cmdbits(OPCODE * op) +{ + TOKEN * t; + int bitno; + char ch; + char * e; + char * q; + int len; + char * s, *brkt = NULL; + int rv = 0; + + bitno = 32; + while (lsize(string_list)) { + + t = lrmv_n(string_list, 1); + + s = strtok_r(t->value.string, " ", &brkt); + while (rv == 0 && s != NULL) { + + bitno--; + if (bitno < 0) { + yyerror("too many opcode bits for instruction"); + rv = -1; + break; + } + + len = strlen(s); + + if (len == 0) { + yyerror("invalid bit specifier \"\""); + rv = -1; + break; + } + + ch = s[0]; + + if (len == 1) { + switch (ch) { + case '1': + op->bit[bitno].type = AVR_CMDBIT_VALUE; + op->bit[bitno].value = 1; + op->bit[bitno].bitno = bitno % 8; + break; + case '0': + op->bit[bitno].type = AVR_CMDBIT_VALUE; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'x': + op->bit[bitno].type = AVR_CMDBIT_IGNORE; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'a': + op->bit[bitno].type = AVR_CMDBIT_ADDRESS; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = 8*(bitno/8) + bitno % 8; + break; + case 'i': + op->bit[bitno].type = AVR_CMDBIT_INPUT; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'o': + op->bit[bitno].type = AVR_CMDBIT_OUTPUT; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + default : + yyerror("invalid bit specifier '%c'", ch); + rv = -1; + break; + } + } + else { + if (ch == 'a') { + q = &s[1]; + op->bit[bitno].bitno = strtol(q, &e, 0); + if ((e == q)||(*e != 0)) { + yyerror("can't parse bit number from \"%s\"", q); + rv = -1; + break; + } + op->bit[bitno].type = AVR_CMDBIT_ADDRESS; + op->bit[bitno].value = 0; + } + else { + yyerror("invalid bit specifier \"%s\"", s); + rv = -1; + break; + } + } + + s = strtok_r(NULL, " ", &brkt); + } /* while */ + + free_token(t); + + } /* while */ + + return rv; +} diff --git a/msvc/generated/config_gram.h b/msvc/generated/config_gram.h new file mode 100644 index 00000000..08f55c9c --- /dev/null +++ b/msvc/generated/config_gram.h @@ -0,0 +1,340 @@ +/* A Bison parser, made by GNU Bison 3.5.1. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_YY_CONFIG_GRAM_H_INCLUDED +# define YY_YY_CONFIG_GRAM_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + K_READ = 258, + K_WRITE = 259, + K_READ_LO = 260, + K_READ_HI = 261, + K_WRITE_LO = 262, + K_WRITE_HI = 263, + K_LOADPAGE_LO = 264, + K_LOADPAGE_HI = 265, + K_LOAD_EXT_ADDR = 266, + K_WRITEPAGE = 267, + K_CHIP_ERASE = 268, + K_PGM_ENABLE = 269, + K_MEMORY = 270, + K_PAGE_SIZE = 271, + K_PAGED = 272, + K_BAUDRATE = 273, + K_BS2 = 274, + K_BUFF = 275, + K_CHIP_ERASE_DELAY = 276, + K_CONNTYPE = 277, + K_DEDICATED = 278, + K_DEFAULT_BITCLOCK = 279, + K_DEFAULT_PARALLEL = 280, + K_DEFAULT_PROGRAMMER = 281, + K_DEFAULT_SAFEMODE = 282, + K_DEFAULT_SERIAL = 283, + K_DESC = 284, + K_FAMILY_ID = 285, + K_DEVICECODE = 286, + K_STK500_DEVCODE = 287, + K_AVR910_DEVCODE = 288, + K_EEPROM = 289, + K_ERRLED = 290, + K_FLASH = 291, + K_ID = 292, + K_IO = 293, + K_LOADPAGE = 294, + K_MAX_WRITE_DELAY = 295, + K_MCU_BASE = 296, + K_MIN_WRITE_DELAY = 297, + K_MISO = 298, + K_MOSI = 299, + K_NUM_PAGES = 300, + K_NVM_BASE = 301, + K_OCD_BASE = 302, + K_OCDREV = 303, + K_OFFSET = 304, + K_PAGEL = 305, + K_PARALLEL = 306, + K_PARENT = 307, + K_PART = 308, + K_PGMLED = 309, + K_PROGRAMMER = 310, + K_PSEUDO = 311, + K_PWROFF_AFTER_WRITE = 312, + K_RDYLED = 313, + K_READBACK_P1 = 314, + K_READBACK_P2 = 315, + K_READMEM = 316, + K_RESET = 317, + K_RETRY_PULSE = 318, + K_SERIAL = 319, + K_SCK = 320, + K_SIGNATURE = 321, + K_SIZE = 322, + K_USB = 323, + K_USBDEV = 324, + K_USBSN = 325, + K_USBPID = 326, + K_USBPRODUCT = 327, + K_USBVENDOR = 328, + K_USBVID = 329, + K_TYPE = 330, + K_VCC = 331, + K_VFYLED = 332, + K_NO = 333, + K_YES = 334, + K_TIMEOUT = 335, + K_STABDELAY = 336, + K_CMDEXEDELAY = 337, + K_HVSPCMDEXEDELAY = 338, + K_SYNCHLOOPS = 339, + K_BYTEDELAY = 340, + K_POLLVALUE = 341, + K_POLLINDEX = 342, + K_PREDELAY = 343, + K_POSTDELAY = 344, + K_POLLMETHOD = 345, + K_MODE = 346, + K_DELAY = 347, + K_BLOCKSIZE = 348, + K_READSIZE = 349, + K_HVENTERSTABDELAY = 350, + K_PROGMODEDELAY = 351, + K_LATCHCYCLES = 352, + K_TOGGLEVTG = 353, + K_POWEROFFDELAY = 354, + K_RESETDELAYMS = 355, + K_RESETDELAYUS = 356, + K_HVLEAVESTABDELAY = 357, + K_RESETDELAY = 358, + K_SYNCHCYCLES = 359, + K_HVCMDEXEDELAY = 360, + K_CHIPERASEPULSEWIDTH = 361, + K_CHIPERASEPOLLTIMEOUT = 362, + K_CHIPERASETIME = 363, + K_PROGRAMFUSEPULSEWIDTH = 364, + K_PROGRAMFUSEPOLLTIMEOUT = 365, + K_PROGRAMLOCKPULSEWIDTH = 366, + K_PROGRAMLOCKPOLLTIMEOUT = 367, + K_PP_CONTROLSTACK = 368, + K_HVSP_CONTROLSTACK = 369, + K_ALLOWFULLPAGEBITSTREAM = 370, + K_ENABLEPAGEPROGRAMMING = 371, + K_HAS_JTAG = 372, + K_HAS_DW = 373, + K_HAS_PDI = 374, + K_HAS_UPDI = 375, + K_HAS_TPI = 376, + K_IDR = 377, + K_IS_AT90S1200 = 378, + K_IS_AVR32 = 379, + K_RAMPZ = 380, + K_SPMCR = 381, + K_EECR = 382, + K_FLASH_INSTR = 383, + K_EEPROM_INSTR = 384, + TKN_COMMA = 385, + TKN_EQUAL = 386, + TKN_SEMI = 387, + TKN_TILDE = 388, + TKN_LEFT_PAREN = 389, + TKN_RIGHT_PAREN = 390, + TKN_NUMBER = 391, + TKN_NUMBER_REAL = 392, + TKN_STRING = 393 + }; +#endif +/* Tokens. */ +#define K_READ 258 +#define K_WRITE 259 +#define K_READ_LO 260 +#define K_READ_HI 261 +#define K_WRITE_LO 262 +#define K_WRITE_HI 263 +#define K_LOADPAGE_LO 264 +#define K_LOADPAGE_HI 265 +#define K_LOAD_EXT_ADDR 266 +#define K_WRITEPAGE 267 +#define K_CHIP_ERASE 268 +#define K_PGM_ENABLE 269 +#define K_MEMORY 270 +#define K_PAGE_SIZE 271 +#define K_PAGED 272 +#define K_BAUDRATE 273 +#define K_BS2 274 +#define K_BUFF 275 +#define K_CHIP_ERASE_DELAY 276 +#define K_CONNTYPE 277 +#define K_DEDICATED 278 +#define K_DEFAULT_BITCLOCK 279 +#define K_DEFAULT_PARALLEL 280 +#define K_DEFAULT_PROGRAMMER 281 +#define K_DEFAULT_SAFEMODE 282 +#define K_DEFAULT_SERIAL 283 +#define K_DESC 284 +#define K_FAMILY_ID 285 +#define K_DEVICECODE 286 +#define K_STK500_DEVCODE 287 +#define K_AVR910_DEVCODE 288 +#define K_EEPROM 289 +#define K_ERRLED 290 +#define K_FLASH 291 +#define K_ID 292 +#define K_IO 293 +#define K_LOADPAGE 294 +#define K_MAX_WRITE_DELAY 295 +#define K_MCU_BASE 296 +#define K_MIN_WRITE_DELAY 297 +#define K_MISO 298 +#define K_MOSI 299 +#define K_NUM_PAGES 300 +#define K_NVM_BASE 301 +#define K_OCD_BASE 302 +#define K_OCDREV 303 +#define K_OFFSET 304 +#define K_PAGEL 305 +#define K_PARALLEL 306 +#define K_PARENT 307 +#define K_PART 308 +#define K_PGMLED 309 +#define K_PROGRAMMER 310 +#define K_PSEUDO 311 +#define K_PWROFF_AFTER_WRITE 312 +#define K_RDYLED 313 +#define K_READBACK_P1 314 +#define K_READBACK_P2 315 +#define K_READMEM 316 +#define K_RESET 317 +#define K_RETRY_PULSE 318 +#define K_SERIAL 319 +#define K_SCK 320 +#define K_SIGNATURE 321 +#define K_SIZE 322 +#define K_USB 323 +#define K_USBDEV 324 +#define K_USBSN 325 +#define K_USBPID 326 +#define K_USBPRODUCT 327 +#define K_USBVENDOR 328 +#define K_USBVID 329 +#define K_TYPE 330 +#define K_VCC 331 +#define K_VFYLED 332 +#define K_NO 333 +#define K_YES 334 +#define K_TIMEOUT 335 +#define K_STABDELAY 336 +#define K_CMDEXEDELAY 337 +#define K_HVSPCMDEXEDELAY 338 +#define K_SYNCHLOOPS 339 +#define K_BYTEDELAY 340 +#define K_POLLVALUE 341 +#define K_POLLINDEX 342 +#define K_PREDELAY 343 +#define K_POSTDELAY 344 +#define K_POLLMETHOD 345 +#define K_MODE 346 +#define K_DELAY 347 +#define K_BLOCKSIZE 348 +#define K_READSIZE 349 +#define K_HVENTERSTABDELAY 350 +#define K_PROGMODEDELAY 351 +#define K_LATCHCYCLES 352 +#define K_TOGGLEVTG 353 +#define K_POWEROFFDELAY 354 +#define K_RESETDELAYMS 355 +#define K_RESETDELAYUS 356 +#define K_HVLEAVESTABDELAY 357 +#define K_RESETDELAY 358 +#define K_SYNCHCYCLES 359 +#define K_HVCMDEXEDELAY 360 +#define K_CHIPERASEPULSEWIDTH 361 +#define K_CHIPERASEPOLLTIMEOUT 362 +#define K_CHIPERASETIME 363 +#define K_PROGRAMFUSEPULSEWIDTH 364 +#define K_PROGRAMFUSEPOLLTIMEOUT 365 +#define K_PROGRAMLOCKPULSEWIDTH 366 +#define K_PROGRAMLOCKPOLLTIMEOUT 367 +#define K_PP_CONTROLSTACK 368 +#define K_HVSP_CONTROLSTACK 369 +#define K_ALLOWFULLPAGEBITSTREAM 370 +#define K_ENABLEPAGEPROGRAMMING 371 +#define K_HAS_JTAG 372 +#define K_HAS_DW 373 +#define K_HAS_PDI 374 +#define K_HAS_UPDI 375 +#define K_HAS_TPI 376 +#define K_IDR 377 +#define K_IS_AT90S1200 378 +#define K_IS_AVR32 379 +#define K_RAMPZ 380 +#define K_SPMCR 381 +#define K_EECR 382 +#define K_FLASH_INSTR 383 +#define K_EEPROM_INSTR 384 +#define TKN_COMMA 385 +#define TKN_EQUAL 386 +#define TKN_SEMI 387 +#define TKN_TILDE 388 +#define TKN_LEFT_PAREN 389 +#define TKN_RIGHT_PAREN 390 +#define TKN_NUMBER 391 +#define TKN_NUMBER_REAL 392 +#define TKN_STRING 393 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_CONFIG_GRAM_H_INCLUDED */ diff --git a/msvc/generated/lexer.c b/msvc/generated/lexer.c new file mode 100644 index 00000000..c00cd8fd --- /dev/null +++ b/msvc/generated/lexer.c @@ -0,0 +1,3092 @@ + +#line 3 "lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 159 +#define YY_END_OF_BUFFER 160 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[894] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 158, + 156, 155, 7, 9, 153, 154, 149, 158, 158, 4, + 4, 151, 150, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 152, 20, 21, 13, 159, 159, 10, + 11, 156, 0, 3, 1, 6, 12, 5, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 66, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 19, + 17, 18, 14, 16, 15, 3, 2, 5, 8, 0, + 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 135, 142, 0, + + 0, 148, 2, 0, 0, 0, 0, 0, 29, 0, + 0, 0, 0, 0, 0, 0, 45, 0, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, 78, 79, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, + 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, + 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 44, 0, 0, 0, 0, 0, 53, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 88, 89, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110, 0, 0, 0, 0, 118, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 0, 0, 144, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 0, 52, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, + + 0, 0, 0, 0, 85, 86, 0, 0, 91, 0, + 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 111, 0, 0, 0, 0, 0, 0, 124, + 0, 0, 0, 0, 0, 0, 0, 136, 137, 0, + 0, 141, 143, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 57, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 113, 114, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 59, 0, 0, 0, 0, 0, 68, + 0, 0, 0, 0, 74, 0, 0, 0, 83, 84, + 0, 90, 0, 0, 0, 0, 0, 0, 0, 101, + 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 145, 146, 0, + 0, 0, 24, 27, 30, 0, 0, 0, 0, 38, + 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 82, 87, 0, 95, 0, 97, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 128, 0, + 0, 0, 133, 0, 140, 147, 0, 0, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 96, 0, 0, 0, 0, + 0, 107, 0, 0, 119, 0, 0, 0, 131, 138, + 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, + + 0, 0, 69, 0, 71, 72, 0, 0, 0, 0, + 0, 0, 0, 0, 115, 116, 0, 0, 122, 0, + 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, + 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 120, 121, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 70, 0, 0, 99, 0, 102, 0, 0, 0, + 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, + 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, + 0, 63, 73, 76, 100, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 39, 40, 0, 42, 0, 60, + 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 0, 0, 0, 0, 0, 109, 0, 0, + 34, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 51, 0, 104, 0, 106, 22, + 103, 105, 0 + + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 1, 1, 1, 6, + 7, 8, 9, 10, 9, 11, 12, 13, 14, 15, + 16, 17, 18, 17, 17, 17, 19, 20, 21, 1, + 22, 1, 1, 1, 23, 23, 23, 23, 23, 23, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 24, 1, 1, 25, 1, 26, 27, 28, 29, + + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 1, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 1, 1, 1, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[52] = + { 0, + 1, 1, 2, 2, 1, 1, 1, 1, 3, 1, + 4, 1, 5, 5, 5, 5, 5, 5, 5, 1, + 1, 1, 6, 2, 1, 6, 6, 6, 6, 6, + 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, + 1 + } ; + +static const flex_int16_t yy_base[902] = + { 0, + 0, 0, 49, 51, 0, 0, 993, 992, 994, 997, + 991, 997, 997, 47, 997, 997, 997, 46, 984, 46, + 55, 997, 997, 30, 42, 50, 961, 39, 45, 46, + 55, 60, 71, 62, 46, 78, 83, 94, 83, 947, + 65, 947, 958, 997, 0, 997, 997, 100, 997, 997, + 997, 985, 105, 132, 125, 139, 997, 146, 0, 0, + 949, 943, 127, 944, 968, 951, 937, 997, 946, 950, + 939, 138, 142, 951, 934, 937, 948, 930, 143, 930, + 997, 946, 926, 943, 920, 922, 928, 87, 86, 997, + 927, 926, 934, 931, 136, 923, 142, 935, 147, 929, + + 916, 919, 907, 148, 919, 912, 144, 915, 162, 913, + 913, 918, 908, 921, 919, 897, 911, 901, 0, 997, + 997, 997, 997, 997, 997, 186, 193, 200, 0, 903, + 923, 905, 911, 911, 997, 907, 907, 895, 905, 895, + 899, 906, 905, 902, 895, 886, 885, 899, 888, 890, + 880, 897, 882, 890, 878, 997, 892, 889, 887, 890, + 889, 873, 887, 871, 880, 875, 883, 882, 64, 863, + 875, 194, 196, 867, 859, 872, 873, 871, 867, 853, + 857, 855, 858, 865, 863, 850, 997, 857, 851, 859, + 860, 860, 868, 857, 854, 851, 852, 193, 997, 844, + + 836, 997, 212, 832, 864, 165, 835, 840, 997, 846, + 207, 826, 843, 844, 826, 821, 997, 841, 997, 828, + 830, 836, 828, 831, 206, 819, 836, 112, 196, 828, + 218, 813, 832, 816, 810, 997, 997, 997, 155, 829, + 828, 824, 823, 219, 815, 812, 997, 820, 819, 211, + 819, 805, 806, 815, 155, 815, 812, 792, 811, 227, + 796, 790, 812, 811, 997, 794, 806, 821, 800, 792, + 794, 997, 800, 99, 790, 228, 798, 797, 795, 812, + 781, 794, 796, 778, 790, 789, 776, 787, 788, 789, + 777, 997, 783, 774, 781, 781, 760, 783, 777, 762, + + 776, 763, 762, 772, 755, 772, 761, 779, 755, 768, + 765, 768, 751, 766, 742, 748, 763, 762, 761, 760, + 739, 740, 740, 997, 997, 745, 737, 741, 750, 739, + 747, 750, 745, 734, 734, 735, 731, 744, 729, 737, + 997, 738, 227, 740, 731, 735, 738, 725, 717, 997, + 730, 746, 218, 713, 727, 710, 726, 714, 997, 714, + 723, 722, 228, 705, 724, 714, 997, 703, 712, 708, + 702, 717, 713, 697, 696, 695, 710, 712, 695, 997, + 710, 700, 706, 706, 697, 696, 700, 686, 697, 686, + 696, 711, 707, 673, 673, 688, 685, 675, 997, 683, + + 677, 683, 671, 670, 997, 997, 678, 681, 997, 684, + 997, 680, 664, 670, 669, 674, 660, 677, 673, 663, + 997, 675, 997, 665, 658, 669, 646, 665, 653, 997, + 648, 655, 666, 641, 649, 644, 641, 997, 997, 657, + 656, 997, 997, 228, 658, 646, 653, 631, 650, 629, + 652, 651, 633, 645, 640, 643, 647, 631, 636, 643, + 634, 628, 621, 633, 997, 997, 630, 620, 619, 622, + 630, 616, 643, 629, 612, 625, 610, 623, 608, 615, + 620, 619, 618, 597, 609, 618, 614, 610, 597, 615, + 609, 597, 589, 607, 235, 610, 997, 997, 599, 604, + + 596, 587, 589, 604, 600, 600, 587, 997, 582, 580, + 584, 589, 582, 589, 583, 589, 588, 997, 587, 567, + 572, 584, 576, 572, 582, 236, 581, 570, 576, 578, + 563, 573, 997, 997, 560, 559, 558, 553, 586, 997, + 562, 573, 572, 566, 997, 565, 551, 550, 997, 997, + 562, 997, 554, 542, 549, 558, 538, 557, 545, 997, + 555, 538, 542, 551, 549, 554, 997, 552, 540, 546, + 526, 544, 536, 531, 539, 542, 527, 997, 997, 538, + 526, 520, 997, 997, 997, 535, 227, 538, 524, 997, + 528, 241, 248, 531, 517, 529, 997, 514, 510, 530, + + 529, 512, 523, 537, 521, 524, 243, 524, 523, 997, + 997, 997, 517, 997, 517, 997, 997, 515, 507, 513, + 499, 513, 498, 495, 497, 488, 493, 997, 997, 489, + 504, 490, 997, 488, 997, 997, 505, 502, 504, 241, + 494, 478, 501, 481, 482, 483, 491, 479, 997, 476, + 478, 476, 483, 489, 488, 474, 484, 499, 468, 481, + 475, 468, 478, 477, 997, 997, 468, 461, 466, 472, + 465, 997, 470, 270, 237, 455, 454, 37, 997, 997, + 139, 183, 258, 251, 252, 252, 997, 247, 264, 267, + 262, 265, 262, 255, 256, 997, 257, 271, 272, 265, + + 273, 291, 997, 276, 997, 997, 276, 277, 282, 265, + 284, 270, 271, 271, 997, 997, 271, 272, 997, 276, + 997, 287, 289, 289, 283, 278, 292, 274, 287, 288, + 284, 289, 302, 997, 289, 300, 301, 302, 290, 297, + 997, 293, 299, 300, 289, 313, 291, 301, 302, 318, + 997, 997, 315, 318, 318, 312, 306, 321, 997, 311, + 313, 317, 329, 316, 320, 326, 997, 322, 323, 317, + 336, 997, 337, 338, 997, 337, 997, 329, 330, 331, + 332, 323, 341, 338, 997, 347, 340, 328, 346, 349, + 348, 341, 351, 997, 339, 356, 357, 358, 336, 337, + + 338, 352, 352, 347, 354, 349, 351, 997, 350, 346, + 358, 363, 997, 362, 362, 362, 371, 376, 354, 355, + 377, 997, 997, 997, 997, 362, 377, 364, 379, 376, + 368, 997, 382, 384, 997, 997, 384, 997, 377, 997, + 997, 380, 383, 371, 385, 373, 377, 378, 383, 380, + 383, 388, 997, 389, 394, 391, 396, 401, 390, 388, + 401, 997, 401, 406, 408, 408, 410, 997, 410, 397, + 997, 403, 403, 400, 405, 402, 421, 997, 416, 404, + 417, 406, 419, 415, 997, 410, 997, 411, 997, 997, + 997, 997, 997, 455, 462, 469, 474, 476, 483, 490, + + 493 + } ; + +static const flex_int16_t yy_def[902] = + { 0, + 893, 1, 894, 894, 895, 895, 896, 896, 893, 893, + 893, 893, 893, 897, 893, 893, 893, 893, 893, 898, + 898, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 899, 893, 893, 900, 893, 893, + 893, 893, 897, 893, 897, 893, 893, 893, 21, 901, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 899, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 901, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 0, 893, 893, 893, 893, 893, 893, 893, + + 893 + } ; + +static const flex_int16_t yy_nxt[1049] = + { 0, + 10, 11, 12, 13, 14, 15, 16, 10, 10, 17, + 18, 19, 20, 21, 21, 21, 21, 21, 21, 10, + 22, 23, 10, 10, 10, 24, 25, 26, 27, 28, + 29, 10, 30, 31, 10, 10, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 10, 43, 10, + 44, 46, 47, 46, 47, 53, 58, 54, 56, 56, + 56, 56, 56, 56, 56, 58, 61, 63, 73, 68, + 76, 78, 48, 93, 48, 62, 94, 74, 64, 721, + 75, 77, 69, 80, 65, 83, 66, 70, 241, 71, + 67, 79, 115, 60, 81, 116, 85, 82, 86, 84, + + 87, 90, 893, 95, 88, 242, 91, 92, 102, 96, + 89, 103, 104, 53, 165, 54, 111, 97, 98, 99, + 100, 105, 112, 106, 101, 163, 121, 107, 166, 164, + 122, 113, 357, 893, 108, 127, 306, 109, 123, 307, + 358, 124, 110, 125, 126, 126, 126, 126, 126, 126, + 126, 56, 56, 56, 56, 56, 56, 56, 128, 128, + 128, 128, 128, 128, 128, 132, 141, 171, 142, 146, + 722, 133, 153, 184, 143, 189, 178, 172, 174, 154, + 144, 317, 147, 145, 175, 155, 179, 192, 176, 281, + 185, 186, 337, 190, 282, 318, 338, 193, 126, 126, + + 126, 126, 126, 126, 126, 203, 203, 203, 203, 203, + 203, 203, 128, 128, 128, 128, 128, 128, 128, 245, + 248, 273, 723, 246, 203, 203, 203, 203, 203, 203, + 203, 286, 249, 274, 299, 275, 287, 247, 276, 308, + 300, 309, 311, 323, 330, 434, 301, 324, 331, 302, + 303, 343, 444, 344, 435, 325, 332, 360, 312, 424, + 512, 361, 591, 425, 513, 562, 645, 640, 445, 345, + 641, 563, 564, 647, 717, 661, 592, 648, 593, 662, + 684, 718, 646, 715, 716, 685, 724, 725, 726, 727, + 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, + + 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, + 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, + 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, + 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, + 778, 780, 782, 783, 784, 779, 781, 785, 786, 787, + 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, + 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, + 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, + 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, + 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, + + 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, + 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, + 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, + 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, + 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, + 888, 889, 890, 891, 892, 45, 45, 45, 45, 45, + 45, 45, 49, 49, 49, 49, 49, 49, 49, 50, + 50, 50, 50, 50, 50, 50, 55, 55, 55, 59, + 59, 720, 59, 119, 719, 119, 119, 119, 119, 119, + 120, 120, 120, 120, 120, 120, 120, 129, 129, 714, + + 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, + 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, + 693, 692, 691, 690, 689, 688, 687, 686, 683, 682, + 681, 680, 679, 678, 677, 676, 675, 674, 673, 672, + 671, 670, 669, 668, 667, 666, 665, 664, 663, 660, + 659, 658, 657, 656, 655, 654, 653, 652, 651, 650, + 649, 644, 643, 642, 639, 638, 637, 636, 635, 634, + 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, + 623, 622, 621, 620, 619, 618, 617, 616, 615, 614, + 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, + + 603, 602, 601, 600, 599, 598, 597, 596, 595, 594, + 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, + 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, + 570, 569, 568, 567, 566, 565, 561, 560, 559, 558, + 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, + 547, 546, 545, 544, 543, 542, 541, 540, 539, 538, + 537, 536, 535, 534, 533, 532, 531, 530, 529, 528, + 527, 526, 525, 524, 523, 522, 521, 520, 519, 518, + 517, 516, 515, 514, 511, 510, 509, 508, 507, 506, + 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, + + 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, + 485, 484, 483, 482, 481, 480, 479, 478, 477, 476, + 475, 474, 473, 472, 471, 470, 469, 468, 467, 466, + 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, + 455, 454, 453, 452, 451, 450, 449, 448, 447, 446, + 443, 442, 441, 440, 439, 438, 437, 436, 433, 432, + 431, 430, 429, 428, 427, 426, 423, 422, 421, 420, + 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, + 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, + 399, 398, 397, 396, 395, 394, 393, 392, 391, 390, + + 389, 388, 387, 386, 385, 384, 383, 382, 381, 380, + 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, + 369, 368, 367, 366, 365, 364, 363, 362, 359, 356, + 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, + 342, 341, 340, 339, 336, 335, 334, 333, 329, 328, + 327, 326, 322, 321, 320, 319, 316, 315, 314, 313, + 310, 305, 304, 298, 297, 296, 295, 294, 293, 292, + 291, 290, 289, 288, 285, 284, 283, 280, 279, 278, + 277, 272, 271, 270, 269, 268, 267, 266, 265, 264, + 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, + + 253, 252, 251, 250, 244, 243, 240, 239, 238, 237, + 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, + 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, + 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, + 206, 205, 204, 202, 201, 200, 199, 198, 197, 196, + 195, 194, 191, 188, 187, 183, 182, 181, 180, 177, + 173, 170, 169, 168, 167, 162, 161, 160, 159, 158, + 157, 156, 152, 151, 150, 149, 148, 140, 139, 138, + 137, 136, 135, 134, 131, 130, 52, 118, 117, 114, + 72, 57, 52, 893, 51, 51, 9, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893 + } ; + +static const flex_int16_t yy_chk[1049] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 4, 4, 14, 20, 14, 18, 18, + 18, 18, 18, 18, 18, 21, 24, 25, 28, 26, + 29, 30, 3, 35, 4, 24, 35, 28, 25, 678, + 28, 29, 26, 31, 25, 32, 25, 26, 169, 26, + 25, 30, 41, 20, 31, 41, 33, 31, 33, 32, + + 33, 34, 21, 36, 33, 169, 34, 34, 37, 36, + 33, 37, 37, 53, 89, 53, 39, 36, 36, 36, + 36, 38, 39, 38, 36, 88, 48, 38, 89, 88, + 48, 39, 274, 55, 38, 55, 228, 38, 48, 228, + 274, 48, 38, 48, 54, 54, 54, 54, 54, 54, + 54, 56, 56, 56, 56, 56, 56, 56, 58, 58, + 58, 58, 58, 58, 58, 63, 72, 95, 72, 73, + 681, 63, 79, 104, 72, 107, 99, 95, 97, 79, + 72, 239, 73, 72, 97, 79, 99, 109, 97, 206, + 104, 104, 255, 107, 206, 239, 255, 109, 126, 126, + + 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, + 127, 127, 128, 128, 128, 128, 128, 128, 128, 172, + 173, 198, 682, 172, 203, 203, 203, 203, 203, 203, + 203, 211, 173, 198, 225, 198, 211, 172, 198, 229, + 225, 229, 231, 244, 250, 353, 225, 244, 250, 225, + 225, 260, 363, 260, 353, 244, 250, 276, 231, 343, + 444, 276, 526, 343, 444, 495, 592, 587, 363, 260, + 587, 495, 495, 593, 675, 607, 526, 593, 526, 607, + 640, 675, 592, 674, 674, 640, 683, 684, 685, 686, + 688, 689, 690, 691, 692, 693, 694, 695, 697, 698, + + 699, 700, 701, 702, 704, 707, 708, 709, 710, 711, + 712, 713, 714, 717, 718, 720, 722, 723, 724, 725, + 726, 727, 728, 729, 730, 731, 732, 733, 735, 736, + 737, 738, 739, 740, 742, 743, 744, 745, 746, 747, + 748, 749, 750, 753, 754, 748, 749, 755, 756, 757, + 758, 760, 761, 762, 763, 764, 765, 766, 768, 769, + 770, 771, 773, 774, 776, 778, 779, 780, 781, 782, + 783, 784, 786, 787, 788, 789, 790, 791, 792, 793, + 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, + 805, 806, 807, 809, 810, 811, 812, 814, 815, 816, + + 817, 818, 819, 820, 821, 826, 827, 828, 829, 830, + 831, 833, 834, 837, 839, 842, 843, 844, 845, 846, + 847, 848, 849, 850, 851, 852, 854, 855, 856, 857, + 858, 859, 860, 861, 863, 864, 865, 866, 867, 869, + 870, 872, 873, 874, 875, 876, 877, 879, 880, 881, + 882, 883, 884, 886, 888, 894, 894, 894, 894, 894, + 894, 894, 895, 895, 895, 895, 895, 895, 895, 896, + 896, 896, 896, 896, 896, 896, 897, 897, 897, 898, + 898, 677, 898, 899, 676, 899, 899, 899, 899, 899, + 900, 900, 900, 900, 900, 900, 900, 901, 901, 673, + + 671, 670, 669, 668, 667, 664, 663, 662, 661, 660, + 659, 658, 657, 656, 655, 654, 653, 652, 651, 650, + 648, 647, 646, 645, 644, 643, 642, 641, 639, 638, + 637, 634, 632, 631, 630, 627, 626, 625, 624, 623, + 622, 621, 620, 619, 618, 615, 613, 609, 608, 606, + 605, 604, 603, 602, 601, 600, 599, 598, 596, 595, + 594, 591, 589, 588, 586, 582, 581, 580, 577, 576, + 575, 574, 573, 572, 571, 570, 569, 568, 566, 565, + 564, 563, 562, 561, 559, 558, 557, 556, 555, 554, + 553, 551, 548, 547, 546, 544, 543, 542, 541, 539, + + 538, 537, 536, 535, 532, 531, 530, 529, 528, 527, + 525, 524, 523, 522, 521, 520, 519, 517, 516, 515, + 514, 513, 512, 511, 510, 509, 507, 506, 505, 504, + 503, 502, 501, 500, 499, 496, 494, 493, 492, 491, + 490, 489, 488, 487, 486, 485, 484, 483, 482, 481, + 480, 479, 478, 477, 476, 475, 474, 473, 472, 471, + 470, 469, 468, 467, 464, 463, 462, 461, 460, 459, + 458, 457, 456, 455, 454, 453, 452, 451, 450, 449, + 448, 447, 446, 445, 441, 440, 437, 436, 435, 434, + 433, 432, 431, 429, 428, 427, 426, 425, 424, 422, + + 420, 419, 418, 417, 416, 415, 414, 413, 412, 410, + 408, 407, 404, 403, 402, 401, 400, 398, 397, 396, + 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, + 385, 384, 383, 382, 381, 379, 378, 377, 376, 375, + 374, 373, 372, 371, 370, 369, 368, 366, 365, 364, + 362, 361, 360, 358, 357, 356, 355, 354, 352, 351, + 349, 348, 347, 346, 345, 344, 342, 340, 339, 338, + 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, + 327, 326, 323, 322, 321, 320, 319, 318, 317, 316, + 315, 314, 313, 312, 311, 310, 309, 308, 307, 306, + + 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, + 295, 294, 293, 291, 290, 289, 288, 287, 286, 285, + 284, 283, 282, 281, 280, 279, 278, 277, 275, 273, + 271, 270, 269, 268, 267, 266, 264, 263, 262, 261, + 259, 258, 257, 256, 254, 253, 252, 251, 249, 248, + 246, 245, 243, 242, 241, 240, 235, 234, 233, 232, + 230, 227, 226, 224, 223, 222, 221, 220, 218, 216, + 215, 214, 213, 212, 210, 208, 207, 205, 204, 201, + 200, 197, 196, 195, 194, 193, 192, 191, 190, 189, + 188, 186, 185, 184, 183, 182, 181, 180, 179, 178, + + 177, 176, 175, 174, 171, 170, 168, 167, 166, 165, + 164, 163, 162, 161, 160, 159, 158, 157, 155, 154, + 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, + 143, 142, 141, 140, 139, 138, 137, 136, 134, 133, + 132, 131, 130, 118, 117, 116, 115, 114, 113, 112, + 111, 110, 108, 106, 105, 103, 102, 101, 100, 98, + 96, 94, 93, 92, 91, 87, 86, 85, 84, 83, + 82, 80, 78, 77, 76, 75, 74, 71, 70, 69, + 67, 66, 65, 64, 62, 61, 52, 43, 42, 40, + 27, 19, 11, 9, 8, 7, 893, 893, 893, 893, + + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "lexer.l" +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000-2004 Brian S. Dean + * Copyright (C) 2006 Joerg Wunsch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* $Id$ */ +#line 23 "lexer.l" +/* need this for the call to atof() below */ +#include +#include +#include +#include +#include +#include + +#include "avrdude.h" +#include "libavrdude.h" +#include "config.h" + +#include "config_gram.h" + +#ifndef YYERRCODE +#define YYERRCODE 256 +#endif + +#line 1008 "lexer.c" + +/* Bump resources for classic lex. */ +#line 1011 "lexer.c" + +#define INITIAL 0 +#define strng 1 +#define incl 2 +#define comment 3 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 57 "lexer.l" + + +#line 1232 "lexer.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 894 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 997 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 59 "lexer.l" +{ yylval = number(yytext); return TKN_NUMBER; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 60 "lexer.l" +{ yylval = number_real(yytext); return TKN_NUMBER_REAL; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 61 "lexer.l" +{ yylval = number_real(yytext); return TKN_NUMBER_REAL; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 62 "lexer.l" +{ yylval = number(yytext); return TKN_NUMBER; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 63 "lexer.l" +{ yylval = number_real(yytext); return TKN_NUMBER_REAL; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 64 "lexer.l" +{ yylval = number_real(yytext); return TKN_NUMBER_REAL; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 66 "lexer.l" +{ string_buf_ptr = string_buf; BEGIN(strng); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 68 "lexer.l" +{ yylval = hexnumber(yytext); return TKN_NUMBER; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 72 "lexer.l" +{ /* The following eats '#' style comments to end of line */ + BEGIN(comment); } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 74 "lexer.l" +{ /* eat comments */ } + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 75 "lexer.l" +{ lineno++; BEGIN(INITIAL); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 78 "lexer.l" +{ /* The following eats multiline C style comments */ + int c; + int comment_start; + + comment_start = lineno; + while (1) { + while (((c = input()) != '*') && (c != EOF)) { + /* eat up text of comment, but keep counting lines */ + if (c == '\n') + lineno++; + } + + if (c == '*') { + while ((c = input()) == '*') + ; + if (c == '/') + break; /* found the end */ + } + + if (c == EOF) { + yyerror("EOF in comment (started on line %d)", comment_start); + return YYERRCODE; + } + } + } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 105 "lexer.l" +{ *string_buf_ptr = 0; string_buf_ptr = string_buf; + yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 107 "lexer.l" +*string_buf_ptr++ = '\n'; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 108 "lexer.l" +*string_buf_ptr++ = '\t'; + YY_BREAK +case 16: +YY_RULE_SETUP +#line 109 "lexer.l" +*string_buf_ptr++ = '\r'; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 110 "lexer.l" +*string_buf_ptr++ = '\b'; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 111 "lexer.l" +*string_buf_ptr++ = '\f'; + YY_BREAK +case 19: +/* rule 19 can match eol */ +YY_RULE_SETUP +#line 112 "lexer.l" +*(string_buf_ptr++) = yytext[1]; + YY_BREAK +case 20: +YY_RULE_SETUP +#line 113 "lexer.l" +{ char *yptr = yytext; while (*yptr) + *(string_buf_ptr++) = *(yptr++); } + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 116 "lexer.l" +{ yyerror("unterminated character constant"); + return YYERRCODE; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 119 "lexer.l" +{ yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 120 "lexer.l" +{ yylval=NULL; return K_AVR910_DEVCODE; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 121 "lexer.l" +{ yylval=NULL; return K_PAGE_SIZE; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 122 "lexer.l" +{ yylval=NULL; return K_PAGED; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 123 "lexer.l" +{ yylval=NULL; return K_BAUDRATE; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 124 "lexer.l" +{ yylval=NULL; return K_BLOCKSIZE; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 125 "lexer.l" +{ yylval=NULL; return K_BS2; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 126 "lexer.l" +{ yylval=NULL; return K_BUFF; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 127 "lexer.l" +{ yylval=NULL; return K_BYTEDELAY; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 128 "lexer.l" +{ yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 129 "lexer.l" +{ yylval=NULL; return K_CHIP_ERASE_DELAY; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 130 "lexer.l" +{ yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 131 "lexer.l" +{ yylval=NULL; return K_CHIPERASEPULSEWIDTH; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 132 "lexer.l" +{ yylval=NULL; return K_CHIPERASETIME; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 133 "lexer.l" +{ yylval=NULL; return K_CMDEXEDELAY; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 134 "lexer.l" +{ yylval=NULL; return K_CONNTYPE; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 135 "lexer.l" +{ yylval=new_token(K_DEDICATED); return K_DEDICATED; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 136 "lexer.l" +{ yylval=NULL; return K_DEFAULT_BITCLOCK; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 137 "lexer.l" +{ yylval=NULL; return K_DEFAULT_PARALLEL; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 138 "lexer.l" +{ yylval=NULL; return K_DEFAULT_PROGRAMMER; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 139 "lexer.l" +{ yylval=NULL; return K_DEFAULT_SAFEMODE; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 140 "lexer.l" +{ yylval=NULL; return K_DEFAULT_SERIAL; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 141 "lexer.l" +{ yylval=NULL; return K_DELAY; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 142 "lexer.l" +{ yylval=NULL; return K_DESC; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 143 "lexer.l" +{ yylval=NULL; return K_FAMILY_ID; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 144 "lexer.l" +{ yylval=NULL; return K_DEVICECODE; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 145 "lexer.l" +{ yylval=NULL; return K_EECR; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 146 "lexer.l" +{ yylval=NULL; return K_EEPROM; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 147 "lexer.l" +{ yylval=NULL; return K_EEPROM_INSTR; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 148 "lexer.l" +{ yylval=NULL; return K_ENABLEPAGEPROGRAMMING; } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 149 "lexer.l" +{ yylval=NULL; return K_ERRLED; } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 150 "lexer.l" +{ yylval=NULL; return K_FLASH; } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 151 "lexer.l" +{ yylval=NULL; return K_FLASH_INSTR; } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 152 "lexer.l" +{ yylval=NULL; return K_HAS_DW; } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 153 "lexer.l" +{ yylval=NULL; return K_HAS_JTAG; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 154 "lexer.l" +{ yylval=NULL; return K_HAS_PDI; } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 155 "lexer.l" +{ yylval=NULL; return K_HAS_TPI; } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 156 "lexer.l" +{ yylval=NULL; return K_HAS_UPDI; } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 157 "lexer.l" +{ yylval=NULL; return K_HVENTERSTABDELAY; } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 158 "lexer.l" +{ yylval=NULL; return K_HVLEAVESTABDELAY; } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 159 "lexer.l" +{ yylval=NULL; return K_HVSP_CONTROLSTACK; } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 160 "lexer.l" +{ yylval=NULL; return K_HVSPCMDEXEDELAY; } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 161 "lexer.l" +{ yylval=NULL; return K_ID; } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 162 "lexer.l" +{ yylval=NULL; return K_IDR; } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 163 "lexer.l" +{ yylval=new_token(K_IO); return K_IO; } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 164 "lexer.l" +{ yylval=NULL; return K_IS_AT90S1200; } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 165 "lexer.l" +{ yylval=NULL; return K_IS_AVR32; } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 166 "lexer.l" +{ yylval=NULL; return K_LATCHCYCLES; } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 167 "lexer.l" +{ yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 168 "lexer.l" +{ yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 169 "lexer.l" +{ yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 170 "lexer.l" +{ yylval=NULL; return K_MAX_WRITE_DELAY; } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 171 "lexer.l" +{ yylval=NULL; return K_MCU_BASE; } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 172 "lexer.l" +{ yylval=NULL; return K_MEMORY; } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 173 "lexer.l" +{ yylval=NULL; return K_MIN_WRITE_DELAY; } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 174 "lexer.l" +{ yylval=NULL; return K_MISO; } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 175 "lexer.l" +{ yylval=NULL; return K_MODE; } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 176 "lexer.l" +{ yylval=NULL; return K_MOSI; } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 177 "lexer.l" +{ yylval=new_token(K_NO); return K_NO; } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 178 "lexer.l" +{ yylval=NULL; return K_NUM_PAGES; } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 179 "lexer.l" +{ yylval=NULL; return K_NUM_PAGES; } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 180 "lexer.l" +{ yylval=NULL; return K_NVM_BASE; } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 181 "lexer.l" +{ yylval=NULL; return K_OCD_BASE; } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 182 "lexer.l" +{ yylval=NULL; return K_OCDREV; } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 183 "lexer.l" +{ yylval=NULL; return K_OFFSET; } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 184 "lexer.l" +{ yylval=NULL; return K_PAGE_SIZE; } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 185 "lexer.l" +{ yylval=NULL; return K_PAGED; } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 186 "lexer.l" +{ yylval=NULL; return K_PAGEL; } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 187 "lexer.l" +{ yylval=NULL; return K_PARALLEL; } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 188 "lexer.l" +{ yylval=NULL; return K_PARENT; } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 189 "lexer.l" +{ yylval=NULL; return K_PART; } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 190 "lexer.l" +{ yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 191 "lexer.l" +{ yylval=NULL; return K_PGMLED; } + YY_BREAK +case 95: +YY_RULE_SETUP +#line 192 "lexer.l" +{ yylval=NULL; return K_POLLINDEX; } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 193 "lexer.l" +{ yylval=NULL; return K_POLLMETHOD; } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 194 "lexer.l" +{ yylval=NULL; return K_POLLVALUE; } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 195 "lexer.l" +{ yylval=NULL; return K_POSTDELAY; } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 196 "lexer.l" +{ yylval=NULL; return K_POWEROFFDELAY; } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 197 "lexer.l" +{ yylval=NULL; return K_PP_CONTROLSTACK; } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 198 "lexer.l" +{ yylval=NULL; return K_PREDELAY; } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 199 "lexer.l" +{ yylval=NULL; return K_PROGMODEDELAY; } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 200 "lexer.l" +{ yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 201 "lexer.l" +{ yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 202 "lexer.l" +{ yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 203 "lexer.l" +{ yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 204 "lexer.l" +{ yylval=NULL; return K_PROGRAMMER; } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 205 "lexer.l" +{ yylval=new_token(K_PSEUDO); return K_PSEUDO; } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 206 "lexer.l" +{ yylval=NULL; return K_PWROFF_AFTER_WRITE; } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 207 "lexer.l" +{ yylval=NULL; return K_RAMPZ; } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 208 "lexer.l" +{ yylval=NULL; return K_RDYLED; } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 209 "lexer.l" +{ yylval=new_token(K_READ); return K_READ; } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 210 "lexer.l" +{ yylval=new_token(K_READ_HI); return K_READ_HI; } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 211 "lexer.l" +{ yylval=new_token(K_READ_LO); return K_READ_LO; } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 212 "lexer.l" +{ yylval=NULL; return K_READBACK_P1; } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 213 "lexer.l" +{ yylval=NULL; return K_READBACK_P2; } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 214 "lexer.l" +{ yylval=NULL; return K_READSIZE; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 215 "lexer.l" +{ yylval=new_token(K_RESET); return K_RESET; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 216 "lexer.l" +{ yylval=NULL; return K_RESETDELAY; } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 217 "lexer.l" +{ yylval=NULL; return K_RESETDELAYMS; } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 218 "lexer.l" +{ yylval=NULL; return K_RESETDELAYUS; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 219 "lexer.l" +{ yylval=NULL; return K_RETRY_PULSE; } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 220 "lexer.l" +{ yylval=new_token(K_SCK); return K_SCK; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 221 "lexer.l" +{ yylval=NULL; return K_SERIAL; } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 222 "lexer.l" +{ yylval=NULL; return K_SIGNATURE; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 223 "lexer.l" +{ yylval=NULL; return K_SIZE; } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 224 "lexer.l" +{ yylval=NULL; return K_SPMCR; } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 225 "lexer.l" +{ yylval=NULL; return K_STABDELAY; } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 226 "lexer.l" +{ yylval=NULL; return K_STK500_DEVCODE; } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 227 "lexer.l" +{ yylval=NULL; return K_SYNCHCYCLES; } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 228 "lexer.l" +{ yylval=NULL; return K_SYNCHLOOPS; } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 229 "lexer.l" +{ yylval=NULL; return K_TIMEOUT; } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 230 "lexer.l" +{ yylval=NULL; return K_TOGGLEVTG; } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 231 "lexer.l" +{ yylval=NULL; return K_TYPE; } + YY_BREAK +case 135: +YY_RULE_SETUP +#line 232 "lexer.l" +{ yylval=NULL; return K_USB; } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 233 "lexer.l" +{ yylval=NULL; return K_USBDEV; } + YY_BREAK +case 137: +YY_RULE_SETUP +#line 234 "lexer.l" +{ yylval=NULL; return K_USBPID; } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 235 "lexer.l" +{ yylval=NULL; return K_USBPRODUCT; } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 236 "lexer.l" +{ yylval=NULL; return K_USBSN; } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 237 "lexer.l" +{ yylval=NULL; return K_USBVENDOR; } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 238 "lexer.l" +{ yylval=NULL; return K_USBVID; } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 239 "lexer.l" +{ yylval=NULL; return K_VCC; } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 240 "lexer.l" +{ yylval=NULL; return K_VFYLED; } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 241 "lexer.l" +{ yylval=new_token(K_WRITE); return K_WRITE; } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 242 "lexer.l" +{ yylval=new_token(K_WRITE_HI); return K_WRITE_HI; } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 243 "lexer.l" +{ yylval=new_token(K_WRITE_LO); return K_WRITE_LO; } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 244 "lexer.l" +{ yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 245 "lexer.l" +{ yylval=new_token(K_YES); return K_YES; } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 247 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_COMMA; } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 248 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_EQUAL; } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 249 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_SEMI; } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 250 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_TILDE; } + YY_BREAK +case 153: +YY_RULE_SETUP +#line 251 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_LEFT_PAREN; } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 252 "lexer.l" +{ yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; } + YY_BREAK +case 155: +/* rule 155 can match eol */ +YY_RULE_SETUP +#line 254 "lexer.l" +{ lineno++; } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 255 "lexer.l" +{ /* ignore whitespace */ } + YY_BREAK +case 157: +YY_RULE_SETUP +#line 257 "lexer.l" +{ yyerror("possible old-style config file entry\n" + " Update your config file (see " CONFIG_DIR + "/avrdude.conf.sample for a sample)"); + return YYERRCODE; } + YY_BREAK +case 158: +YY_RULE_SETUP +#line 262 "lexer.l" +{ return YYERRCODE; } + YY_BREAK +case 159: +YY_RULE_SETUP +#line 264 "lexer.l" +ECHO; + YY_BREAK +#line 2119 "lexer.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(strng): +case YY_STATE_EOF(incl): +case YY_STATE_EOF(comment): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 894 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 894 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 893); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 264 "lexer.l" + + + diff --git a/msvc/getopt.c b/msvc/getopt.c new file mode 100644 index 00000000..ac1fda42 --- /dev/null +++ b/msvc/getopt.c @@ -0,0 +1,562 @@ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char __declspec(dllimport) *__progname; +#endif + +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt,va_list ap) +{ + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); +} + +static void +warnx(const char *fmt,...) +{ + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/msvc/getopt.h b/msvc/getopt.h new file mode 100644 index 00000000..1922a0ef --- /dev/null +++ b/msvc/getopt.h @@ -0,0 +1,95 @@ +#ifndef __GETOPT_H__ +/** + * DISCLAIMER + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * + * The mingw-w64 runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int optind; /* index of first non-option in argv */ +extern int optopt; /* single option character, as parsed */ +extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ + +extern char *optarg; /* pointer to argument of current option */ + +extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; + +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; + +extern int getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ diff --git a/msvc/gettimeofday.c b/msvc/gettimeofday.c new file mode 100644 index 00000000..c7a9844d --- /dev/null +++ b/msvc/gettimeofday.c @@ -0,0 +1,76 @@ +/** +* This file has no copyright assigned and is placed in the Public Domain. +* This file is part of the mingw-w64 runtime package. +* No warranty is given; refer to the file DISCLAIMER.PD within this package. +*/ +#include +#include +#include +#include +#include + +#define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */ +#define HECTONANOSEC_PER_SEC 10000000ull + +int getntptimeofday(struct timespec *, struct timezone *); + +int getntptimeofday(struct timespec *tp, struct timezone *z) +{ + int res = 0; + union + { + unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + TIME_ZONE_INFORMATION TimeZoneInformation; + DWORD tzi; + + if (z != NULL) + { + if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID) + { + z->tz_minuteswest = TimeZoneInformation.Bias; + if (tzi == TIME_ZONE_ID_DAYLIGHT) + z->tz_dsttime = 1; + else + z->tz_dsttime = 0; + } + else + { + z->tz_minuteswest = 0; + z->tz_dsttime = 0; + } + } + + if (tp != NULL) + { + GetSystemTimeAsFileTime(&_now.ft); /* 100-nanoseconds since 1-1-1601 */ + /* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 microseconds = 0.125 milliseconds */ + _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ + tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */ + tp->tv_nsec = (long)(_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */ + } + return res; +} + +int __cdecl gettimeofday(struct timeval *p, void *z) +{ + struct timespec tp; + + if (getntptimeofday(&tp, (struct timezone *) z)) + return -1; + p->tv_sec = (long)tp.tv_sec; + p->tv_usec = (tp.tv_nsec / 1000); + return 0; +} + +int __cdecl mingw_gettimeofday(struct timeval *p, struct timezone *z) +{ + struct timespec tp; + + if (getntptimeofday(&tp, z)) + return -1; + p->tv_sec = (long)tp.tv_sec; + p->tv_usec = (tp.tv_nsec / 1000); + return 0; +} diff --git a/msvc/msvc_compat.h b/msvc/msvc_compat.h new file mode 100644 index 00000000..b0b6a71f --- /dev/null +++ b/msvc/msvc_compat.h @@ -0,0 +1,50 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include + +#pragma warning(disable : 4018) // signed/unsigned mismatch +#pragma warning(disable : 4244) // conversion from '...' to '...', possible loss of data +#pragma warning(disable : 4267) // conversion from '...' to '...', possible loss of data + +#pragma comment(lib, "hid.lib") +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "setupapi.lib") + +#define PATH_MAX _MAX_PATH + +#define setvbuf msvc_setvbuf + +static inline int msvc_setvbuf( + FILE* const public_stream, + char* const buffer, + int const type, + size_t const buffer_size_in_bytes +) +{ + // Just ignore calls to setvbuf with invalid buffer size. + // Purpose of setvbuf calls unknown, probably in an attempt to fix broken + // programs that capture stdout and stderr using separate stream handles? + return 0; +} + +static inline int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1, s2); } +static inline int strncasecmp(const char *s1, const char *s2, size_t n) { return _strnicmp(s1, s2, n); } diff --git a/msvc/sys/time.h b/msvc/sys/time.h new file mode 100644 index 00000000..794ced68 --- /dev/null +++ b/msvc/sys/time.h @@ -0,0 +1,28 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +struct timezone +{ + int tz_minuteswest; + int tz_dsttime; +}; + +#endif diff --git a/msvc/unistd.cpp b/msvc/unistd.cpp new file mode 100644 index 00000000..2b20e700 --- /dev/null +++ b/msvc/unistd.cpp @@ -0,0 +1,93 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "unistd.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#pragma comment(lib, "winmm.lib") + +class MicroSleep +{ +public: + MicroSleep() + { + if (::timeBeginPeriod(timerPeriod) == TIMERR_NOERROR) + { + m_resetTimerPeriod = true; + } + } + + ~MicroSleep() + { + if (m_resetTimerPeriod) + { + ::timeEndPeriod(timerPeriod); + } + } + + int Sleep(DWORD us) + { + if (us == 0) + { + return 0; + } + + LARGE_INTEGER frequency; + if (QueryPerformanceFrequency(&frequency)) + { + LARGE_INTEGER start; + QueryPerformanceCounter(&start); + + if (us > 10000) + { + ::Sleep((us - 5000) / 1000); + } + + LARGE_INTEGER end; + end.QuadPart = start.QuadPart + (frequency.QuadPart * us / 1000000); + + while (true) + { + LARGE_INTEGER current; + QueryPerformanceCounter(¤t); + if (current.QuadPart >= end.QuadPart) + { + break; + } + } + } + else + { + ::Sleep((us / 1000) + 1); + } + + return 0; + } + +private: + static const UINT timerPeriod = 1; // 1ms + bool m_resetTimerPeriod = false; +}; + +int usleep(unsigned int us) +{ + static MicroSleep microSleep; + return microSleep.Sleep(us); +} diff --git a/msvc/unistd.h b/msvc/unistd.h new file mode 100644 index 00000000..89d4df68 --- /dev/null +++ b/msvc/unistd.h @@ -0,0 +1,37 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#define STDIN_FILENO _fileno(stdin) +#define STDERR_FILENO _fileno(stderr) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int usleep(unsigned int us); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pickit2.c b/pickit2.c index bbf8b9ad..d119be73 100644 --- a/pickit2.c +++ b/pickit2.c @@ -59,7 +59,11 @@ #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) #include #if defined(HAVE_DDK_HIDSDI_H) +#ifdef _MSC_VER +# include +#else # include +#endif #else # include "my_ddk_hidsdi.h" #endif @@ -94,7 +98,7 @@ // win32native only: #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) static HANDLE open_hid(unsigned short vid, unsigned short pid); -const char *usb_strerror() +static const char *usb_strerror() { return ""; } diff --git a/ppiwin.c b/ppiwin.c index bedbaf92..e819a220 100644 --- a/ppiwin.c +++ b/ppiwin.c @@ -32,7 +32,7 @@ reg = register as defined in an enum in ppi.h. This must be converted #include "ac_cfg.h" -#if defined (WIN32NATIVE) +#if defined (WIN32NATIVE) && defined (HAVE_PARPORT) #include #include diff --git a/ser_avrdoper.c b/ser_avrdoper.c index 8eae2c3f..4b5664e8 100644 --- a/ser_avrdoper.c +++ b/ser_avrdoper.c @@ -165,11 +165,19 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum #include #if defined(HAVE_DDK_HIDSDI_H) +#ifdef _MSC_VER +# include +#else # include +#endif #else # include "my_ddk_hidsdi.h" #endif +#ifdef _MSC_VER +#include +#else #include +#endif #ifdef USB_DEBUG #define DEBUG_PRINT(arg) printf arg diff --git a/serbb_win32.c b/serbb_win32.c index 0e889745..46002594 100644 --- a/serbb_win32.c +++ b/serbb_win32.c @@ -258,10 +258,27 @@ static int serbb_open(PROGRAMMER *pgm, char *port) DCB dcb; LPVOID lpMsgBuf; HANDLE hComPort = INVALID_HANDLE_VALUE; + char* newname = 0; if (bitbang_check_prerequisites(pgm) < 0) return -1; + if (strncasecmp(port, "com", strlen("com")) == 0) { + + // prepend "\\\\.\\" to name, required for port # >= 10 + newname = malloc(strlen("\\\\.\\") + strlen(port) + 1); + + if (newname == 0) { + avrdude_message(MSG_INFO, "%s: serbb_open(): out of memory\n", + progname); + exit(1); + } + strcpy(newname, "\\\\.\\"); + strcat(newname, port); + + port = newname; + } + hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -308,13 +325,17 @@ static int serbb_open(PROGRAMMER *pgm, char *port) progname, port); return -1; } - avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n", - progname, port, (int)hComPort); + avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%zx\n", + progname, port, (INT_PTR)hComPort); pgm->fd.pfd = (void *)hComPort; dtr = rts = txd = 0; + if (newname != 0) { + free(newname); + } + return 0; } @@ -326,8 +347,8 @@ static void serbb_close(PROGRAMMER *pgm) pgm->setpin(pgm, PIN_AVR_RESET, 1); CloseHandle (hComPort); } - avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%x\n", - progname, (int)hComPort); + avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%zx\n", + progname, (INT_PTR)hComPort); hComPort = INVALID_HANDLE_VALUE; } diff --git a/stk500.c b/stk500.c index a2bf1fb5..167121d5 100644 --- a/stk500.c +++ b/stk500.c @@ -754,12 +754,10 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr) return -1; } - -static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, - unsigned int page_size, +static int stk500_paged_write2(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned char* buf, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - unsigned char buf[page_size + 16]; int memtype; int a_div; int block_size; @@ -850,6 +848,16 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, return n_bytes; } +static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, + unsigned int page_size, + unsigned int addr, unsigned int n_bytes) +{ + unsigned char* buf = malloc(page_size + 16); + int result = stk500_paged_write2(pgm, p, m, buf, page_size, addr, n_bytes); + free(buf); + return result; +} + static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int page_size, unsigned int addr, unsigned int n_bytes)