mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 03:11:39 +01:00 
			
		
		
		
	+ Added fpcres
git-svn-id: trunk@954 -
This commit is contained in:
		
							parent
							
								
									51d0c0ef2a
								
							
						
					
					
						commit
						d570eabe53
					
				
							
								
								
									
										7
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @ -6271,6 +6271,13 @@ utils/fpcm/fpcmpkg.pp svneol=native#text/plain | ||||
| utils/fpcm/fpcmwr.pp svneol=native#text/plain | ||||
| utils/fpcm/makefile.exm -text | ||||
| utils/fpcm/readme.txt svneol=native#text/plain | ||||
| utils/fpcres/Makefile svneol=native#text/plain | ||||
| utils/fpcres/Makefile.fpc svneol=native#text/plain | ||||
| utils/fpcres/elfbfd.pas svneol=native#text/plain | ||||
| utils/fpcres/elfres.pas svneol=native#text/plain | ||||
| utils/fpcres/elfresfix.pas svneol=native#text/plain | ||||
| utils/fpcres/fpcres.lpi svneol=native#text/plain | ||||
| utils/fpcres/fpcres.pas svneol=native#text/plain | ||||
| utils/fpdoc/COPYING -text | ||||
| utils/fpdoc/Makefile svneol=native#text/plain | ||||
| utils/fpdoc/Makefile.fpc svneol=native#text/plain | ||||
|  | ||||
							
								
								
									
										153
									
								
								utils/Makefile
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								utils/Makefile
									
									
									
									
									
								
							| @ -1,8 +1,8 @@ | ||||
| #
 | ||||
| # Don't edit, this file is generated by FPCMake Version 2.0.0 [2005/08/10]
 | ||||
| # Don't edit, this file is generated by FPCMake Version 1.9.8 [2005/04/10]
 | ||||
| #
 | ||||
| default: all | ||||
| MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-emx i386-watcom i386-netwlibc i386-wince m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos powerpc-linux powerpc-netbsd powerpc-macos powerpc-darwin powerpc-morphos sparc-linux sparc-netbsd sparc-solaris x86_64-linux x86_64-freebsd x86_64-win64 arm-linux arm-wince | ||||
| MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-emx i386-watcom i386-netwlibc m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos powerpc-linux powerpc-netbsd powerpc-macos powerpc-darwin powerpc-morphos sparc-linux sparc-netbsd sparc-solaris x86_64-linux x86_64-freebsd arm-linux | ||||
| BSDs = freebsd netbsd openbsd darwin | ||||
| UNIXs = linux $(BSDs) solaris qnx | ||||
| LIMIT83fs = go32v2 os2 emx watcom | ||||
| @ -233,7 +233,7 @@ PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/ext | ||||
| override PACKAGE_NAME=utils | ||||
| override PACKAGE_VERSION=2.0.0 | ||||
| ifeq ($(FULL_TARGET),i386-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-go32v2) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| @ -277,11 +277,8 @@ endif | ||||
| ifeq ($(FULL_TARGET),i386-netwlibc) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-freebsd) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| @ -302,7 +299,7 @@ ifeq ($(FULL_TARGET),m68k-palmos) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),powerpc-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),powerpc-netbsd) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| @ -317,7 +314,7 @@ ifeq ($(FULL_TARGET),powerpc-morphos) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),sparc-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),sparc-netbsd) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| @ -326,19 +323,13 @@ ifeq ($(FULL_TARGET),sparc-solaris) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-freebsd) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| override TARGET_DIRS+=fpcm tply h2pas fprcp dxegen fpdoc  fpcres | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-linux) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| @ -385,9 +376,6 @@ endif | ||||
| ifeq ($(FULL_TARGET),i386-netwlibc) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| @ -439,15 +427,9 @@ endif | ||||
| ifeq ($(FULL_TARGET),x86_64-freebsd) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-linux) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| @ -493,9 +475,6 @@ endif | ||||
| ifeq ($(FULL_TARGET),i386-netwlibc) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| @ -547,15 +526,9 @@ endif | ||||
| ifeq ($(FULL_TARGET),x86_64-freebsd) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| override TARGET_RSTS+=rstconv | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-linux) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| @ -601,9 +574,6 @@ endif | ||||
| ifeq ($(FULL_TARGET),i386-netwlibc) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| @ -655,15 +625,9 @@ endif | ||||
| ifeq ($(FULL_TARGET),x86_64-freebsd) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| override CLEAN_UNITS+=ptopu | ||||
| endif | ||||
| override INSTALL_FPCPACKAGE=y | ||||
| ifdef REQUIRE_UNITSDIR | ||||
| override UNITSDIR+=$(REQUIRE_UNITSDIR) | ||||
| @ -1562,14 +1526,6 @@ REQUIRE_PACKAGES_PASJPEG=1 | ||||
| REQUIRE_PACKAGES_NETDB=1 | ||||
| REQUIRE_PACKAGES_LIBASYNC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| REQUIRE_PACKAGES_RTL=1 | ||||
| REQUIRE_PACKAGES_PASZLIB=1 | ||||
| REQUIRE_PACKAGES_FCL=1 | ||||
| REQUIRE_PACKAGES_PASJPEG=1 | ||||
| REQUIRE_PACKAGES_NETDB=1 | ||||
| REQUIRE_PACKAGES_LIBASYNC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| REQUIRE_PACKAGES_RTL=1 | ||||
| REQUIRE_PACKAGES_PASZLIB=1 | ||||
| @ -1757,14 +1713,6 @@ REQUIRE_PACKAGES_POSTGRES=1 | ||||
| REQUIRE_PACKAGES_MYSQL=1 | ||||
| REQUIRE_PACKAGES_SQLITE=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| REQUIRE_PACKAGES_RTL=1 | ||||
| REQUIRE_PACKAGES_PASZLIB=1 | ||||
| REQUIRE_PACKAGES_FCL=1 | ||||
| REQUIRE_PACKAGES_PASJPEG=1 | ||||
| REQUIRE_PACKAGES_NETDB=1 | ||||
| REQUIRE_PACKAGES_LIBASYNC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| REQUIRE_PACKAGES_RTL=1 | ||||
| REQUIRE_PACKAGES_PASZLIB=1 | ||||
| @ -1778,14 +1726,6 @@ REQUIRE_PACKAGES_POSTGRES=1 | ||||
| REQUIRE_PACKAGES_MYSQL=1 | ||||
| REQUIRE_PACKAGES_SQLITE=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| REQUIRE_PACKAGES_RTL=1 | ||||
| REQUIRE_PACKAGES_PASZLIB=1 | ||||
| REQUIRE_PACKAGES_FCL=1 | ||||
| REQUIRE_PACKAGES_PASJPEG=1 | ||||
| REQUIRE_PACKAGES_NETDB=1 | ||||
| REQUIRE_PACKAGES_LIBASYNC=1 | ||||
| endif | ||||
| ifdef REQUIRE_PACKAGES_RTL | ||||
| PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR)))))) | ||||
| ifneq ($(PACKAGEDIR_RTL),) | ||||
| @ -2121,7 +2061,7 @@ else | ||||
| FPCCPUOPT:= | ||||
| endif | ||||
| endif | ||||
| override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n | ||||
| override FPCOPT+=-Xs $(FPCCPUOPT) -n | ||||
| override FPCOPTDEF+=RELEASE | ||||
| endif | ||||
| ifdef STRIP | ||||
| @ -2601,6 +2541,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-go32v2) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| @ -2715,14 +2656,6 @@ TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),i386-wince) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| TARGET_DIRS_TPLY=1 | ||||
| TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-linux) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| TARGET_DIRS_TPLY=1 | ||||
| @ -2730,6 +2663,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),m68k-freebsd) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| @ -2786,6 +2720,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),powerpc-netbsd) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| @ -2826,6 +2761,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),sparc-netbsd) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| @ -2850,6 +2786,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-freebsd) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| @ -2859,14 +2796,6 @@ TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),x86_64-win64) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| TARGET_DIRS_TPLY=1 | ||||
| TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-linux) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| TARGET_DIRS_TPLY=1 | ||||
| @ -2874,14 +2803,7 @@ TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| endif | ||||
| ifeq ($(FULL_TARGET),arm-wince) | ||||
| TARGET_DIRS_FPCM=1 | ||||
| TARGET_DIRS_TPLY=1 | ||||
| TARGET_DIRS_H2PAS=1 | ||||
| TARGET_DIRS_FPRCP=1 | ||||
| TARGET_DIRS_DXEGEN=1 | ||||
| TARGET_DIRS_FPDOC=1 | ||||
| TARGET_DIRS_FPCRES=1 | ||||
| endif | ||||
| ifdef TARGET_DIRS_FPCM | ||||
| fpcm_all: | ||||
| @ -3153,6 +3075,51 @@ fpdoc: | ||||
| 	$(MAKE) -C fpdoc all | ||||
| .PHONY: fpdoc_all fpdoc_debug fpdoc_smart fpdoc_release fpdoc_units fpdoc_examples fpdoc_shared fpdoc_install fpdoc_sourceinstall fpdoc_exampleinstall fpdoc_distinstall fpdoc_zipinstall fpdoc_zipsourceinstall fpdoc_zipexampleinstall fpdoc_zipdistinstall fpdoc_clean fpdoc_distclean fpdoc_cleanall fpdoc_info fpdoc_makefiles fpdoc | ||||
| endif | ||||
| ifdef TARGET_DIRS_FPCRES | ||||
| fpcres_all: | ||||
| 	$(MAKE) -C fpcres all | ||||
| fpcres_debug: | ||||
| 	$(MAKE) -C fpcres debug | ||||
| fpcres_smart: | ||||
| 	$(MAKE) -C fpcres smart | ||||
| fpcres_release: | ||||
| 	$(MAKE) -C fpcres release | ||||
| fpcres_units: | ||||
| 	$(MAKE) -C fpcres units | ||||
| fpcres_examples: | ||||
| 	$(MAKE) -C fpcres examples | ||||
| fpcres_shared: | ||||
| 	$(MAKE) -C fpcres shared | ||||
| fpcres_install: | ||||
| 	$(MAKE) -C fpcres install | ||||
| fpcres_sourceinstall: | ||||
| 	$(MAKE) -C fpcres sourceinstall | ||||
| fpcres_exampleinstall: | ||||
| 	$(MAKE) -C fpcres exampleinstall | ||||
| fpcres_distinstall: | ||||
| 	$(MAKE) -C fpcres distinstall | ||||
| fpcres_zipinstall: | ||||
| 	$(MAKE) -C fpcres zipinstall | ||||
| fpcres_zipsourceinstall: | ||||
| 	$(MAKE) -C fpcres zipsourceinstall | ||||
| fpcres_zipexampleinstall: | ||||
| 	$(MAKE) -C fpcres zipexampleinstall | ||||
| fpcres_zipdistinstall: | ||||
| 	$(MAKE) -C fpcres zipdistinstall | ||||
| fpcres_clean: | ||||
| 	$(MAKE) -C fpcres clean | ||||
| fpcres_distclean: | ||||
| 	$(MAKE) -C fpcres distclean | ||||
| fpcres_cleanall: | ||||
| 	$(MAKE) -C fpcres cleanall | ||||
| fpcres_info: | ||||
| 	$(MAKE) -C fpcres info | ||||
| fpcres_makefiles: | ||||
| 	$(MAKE) -C fpcres makefiles | ||||
| fpcres: | ||||
| 	$(MAKE) -C fpcres all | ||||
| .PHONY: fpcres_all fpcres_debug fpcres_smart fpcres_release fpcres_units fpcres_examples fpcres_shared fpcres_install fpcres_sourceinstall fpcres_exampleinstall fpcres_distinstall fpcres_zipinstall fpcres_zipsourceinstall fpcres_zipexampleinstall fpcres_zipdistinstall fpcres_clean fpcres_distclean fpcres_cleanall fpcres_info fpcres_makefiles fpcres | ||||
| endif | ||||
| ifdef TARGET_DIRS_FPMC | ||||
| fpmc_all: | ||||
| 	$(MAKE) -C fpmc all | ||||
|  | ||||
| @ -10,6 +10,7 @@ version=2.0.0 | ||||
| dirs=fpcm tply h2pas fprcp dxegen fpdoc | ||||
| programs=ppdep ptop rstconv data2inc delp bin2obj postw32 | ||||
| dirs_win32=fpmc | ||||
| dirs_linux=fpcres | ||||
| rsts=rstconv | ||||
| 
 | ||||
| [require] | ||||
|  | ||||
							
								
								
									
										1519
									
								
								utils/fpcres/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1519
									
								
								utils/fpcres/Makefile
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								utils/fpcres/Makefile.fpc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								utils/fpcres/Makefile.fpc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| #
 | ||||
| #   Makefile.fpc for FPCMake
 | ||||
| #
 | ||||
| 
 | ||||
| [target] | ||||
| programs=fpcres | ||||
| rsts=fpcres fpcresfix elfres | ||||
| 
 | ||||
| [clean] | ||||
| units=fpcresfix elfbfd elfres | ||||
| 
 | ||||
| [require] | ||||
| packages=rtl | ||||
| 
 | ||||
| [install] | ||||
| fpcpackage=y | ||||
| 
 | ||||
| [default] | ||||
| fpcdir=../.. | ||||
| 
 | ||||
| [rules] | ||||
| fpcmake$(EXEEXT): fpcresfix.pas elfbfd.pas elfres.pas fpcres.pas | ||||
							
								
								
									
										150
									
								
								utils/fpcres/elfbfd.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								utils/fpcres/elfbfd.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,150 @@ | ||||
| {$ifdef fpc} | ||||
| {$mode objfpc} | ||||
| {$endif} | ||||
| {$H+} | ||||
| unit elfbfd; | ||||
| 
 | ||||
| {ELF Binary Format Description. 32/64 bit definitions } | ||||
| 
 | ||||
| interface | ||||
| 
 | ||||
| const | ||||
|   SHT_NULL     = 0; | ||||
|   SHT_PROGBITS = 1; | ||||
|   SHT_SYMTAB   = 2; | ||||
|   SHT_STRTAB   = 3; | ||||
|   SHT_RELA     = 4; | ||||
|   SHT_HASH     = 5; | ||||
|   SHT_DYNAMIC  = 6; | ||||
|   SHT_NOTE     = 7; | ||||
|   SHT_NOBITS   = 8; | ||||
|   SHT_REL      = 9; | ||||
|   SHT_SHLIB    = 10; | ||||
|   SHT_DYNSYM   = 11; | ||||
|   SHF_WRITE     = 1; | ||||
|   SHF_ALLOC     = 2; | ||||
|   SHF_EXECINSTR = 4; | ||||
| 
 | ||||
|   PT_NULL       = 0; | ||||
|   PT_LOAD 	= 1; | ||||
|   PT_DYNAMIC 	= 2; | ||||
|   PT_INTERP 	= 3; | ||||
|   PT_NOTE 	= 4; | ||||
|   PT_SHLIB 	= 5; | ||||
|   PT_PHDR 	= 6; | ||||
|   PT_LOOS 	= $60000000; | ||||
|   PT_HIOS 	= $6fffffff; | ||||
|   PT_LOPROC 	= $70000000; | ||||
|   PT_HIPROC 	= $7fffffff; | ||||
| 
 | ||||
| Type | ||||
|   TElf32header = packed record | ||||
|     magic0123: longint; | ||||
|     file_class: byte; | ||||
|     data_encoding: byte; | ||||
|     file_version: byte; | ||||
|     padding: array[$07..$0F] of byte; | ||||
|     e_type: word; | ||||
|     e_machine: word; | ||||
|     e_version: longint; | ||||
|     e_entry: longint; { entrypoint } | ||||
|     e_phoff: longint; { program header offset } | ||||
|     e_shoff: longint; { sections header offset } | ||||
|     e_flags: longint; | ||||
|     e_ehsize: word; { elf header size in bytes } | ||||
|     e_phentsize: word; { size of an entry in the program header array } | ||||
|     e_phnum: word; { 0..e_phnum-1 of entrys } | ||||
|     e_shentsize: word; { size of an entry in sections header array } | ||||
|     e_shnum: word; { 0..e_shnum-1 of entrys } | ||||
|     e_shstrndx: word; { index of string section header } | ||||
|   end; | ||||
| 
 | ||||
|   TElf64header = packed record | ||||
|     magic0123: longint; | ||||
|     file_class: byte; | ||||
|     data_encoding: byte; | ||||
|     file_version: byte; | ||||
|     padding: array[$07..$0F] of byte; | ||||
|     e_type: word; | ||||
|     e_machine: word; | ||||
|     e_version: longint; | ||||
|     e_entry: int64; { entrypoint } | ||||
|     e_phoff: int64; { program header offset } | ||||
|     e_shoff: int64; { sections header offset } | ||||
|     e_flags: longint; | ||||
|     e_ehsize: word; { elf header size in bytes } | ||||
|     e_phentsize: word; { size of an entry in the program header array } | ||||
|     e_phnum: word; { 0..e_phnum-1 of entrys } | ||||
|     e_shentsize: word; { size of an entry in sections header array } | ||||
|     e_shnum: word; { 0..e_shnum-1 of entrys } | ||||
|     e_shstrndx: word; { index of string section header } | ||||
|   end; | ||||
| 
 | ||||
|   TElf32sechdr = packed record | ||||
|     sh_name: longint; | ||||
|     sh_type: longint; | ||||
|     sh_flags: longint; | ||||
|     sh_addr: longint; | ||||
|     sh_offset: longint; | ||||
|     sh_size: longint; | ||||
|     sh_link: longint; | ||||
|     sh_info: longint; | ||||
|     sh_addralign: longint; | ||||
|     sh_entsize: longint; | ||||
|   end; | ||||
| 
 | ||||
|   TElf64sechdr = packed record | ||||
|     sh_name: longint; | ||||
|     sh_type: longint; | ||||
|     sh_flags: longint; | ||||
|     sh_addr: int64; | ||||
|     sh_offset: int64; | ||||
|     sh_size: int64; | ||||
|     sh_link: longint; | ||||
|     sh_info: longint; | ||||
|     sh_addralign: int64; | ||||
|     sh_entsize: int64; | ||||
|   end; | ||||
|    | ||||
|   { FPC resources } | ||||
|    | ||||
|   TELF32ResourceSectionInfo = packed record | ||||
|     ptr: longint; | ||||
|     size: longint; | ||||
|   end; | ||||
| 
 | ||||
|   TELF64ResourceSectionInfo = packed record | ||||
|     ptr: int64; | ||||
|     size: int64; | ||||
|   end; | ||||
| 
 | ||||
|   TELF32ResourceInfo = packed record | ||||
|     reshash: longint; // always 32bit, contains an ELF hash of the resource entries name | ||||
|     restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs | ||||
|     ptr:     longint; // Byte offset to the resource inside the resdata section. | ||||
|     name:    longint; // Byte offset to the the resource name inside the ressym section. | ||||
|     size:    longint; // The size of the resource entry | ||||
|   end; | ||||
| 
 | ||||
|   TELF64ResourceInfo = packed record | ||||
|     reshash: longint; // always 32bit, contains an ELF hash of the resource entries name | ||||
|     restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs | ||||
|     ptr:     int64;   // Byte offset to the resource inside the resdata section. | ||||
|     name:    int64;   // Byte offset to the the resource name inside the ressym section. | ||||
|     size:    int64;   // The size of the resource entry | ||||
|   end; | ||||
| 
 | ||||
|   TELF32ResourceSectionTable = packed record | ||||
|     version: integer; | ||||
|     resentries: integer; | ||||
|     ressym: TELF32ResourceSectionInfo; | ||||
|     reshash: TELF32ResourceSectionInfo; | ||||
|     resdata: TELF32ResourceSectionInfo; | ||||
|     resspare: TELF32ResourceSectionInfo; | ||||
|     resstr: TELF32ResourceSectionInfo; | ||||
|   end; | ||||
| 
 | ||||
| implementation | ||||
| 
 | ||||
| end. | ||||
| 
 | ||||
							
								
								
									
										692
									
								
								utils/fpcres/elfres.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										692
									
								
								utils/fpcres/elfres.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,692 @@ | ||||
| { *********************************************************************** } | ||||
| {                                                                         } | ||||
| {  fpcres2elf - Free Pascal Resource to ELF object compiler               } | ||||
| {  Part of the Free Pascal and CrossFPC distributions                     } | ||||
| {                                                                         } | ||||
| {  Copyright (C) 2005 Simon Kissel                                        } | ||||
| {                                                                         } | ||||
| {  See the file COPYING.FPC, included in the FPC distribution,            } | ||||
| {  for details about the copyright.                                       } | ||||
| {                                                                         } | ||||
| {  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.                   } | ||||
| {                                                                         } | ||||
| { *********************************************************************** } | ||||
| 
 | ||||
| { | ||||
| This unit will compile an ELF object file out of a supplied .res resource | ||||
| file. Optionally, Delphi/Kylix dfm/xfm form files are also accepted as | ||||
| input. These will automatically be converted into resources internally. | ||||
| 
 | ||||
| fpcres2elf builds with Delphi, Kylix and FPC. | ||||
| 
 | ||||
| Currently this only works on 32Bit targets, but support for 64Bit targets | ||||
| is in the works. Support for big endian systems is completely missing, | ||||
| though. | ||||
| 
 | ||||
| Format used for the various resource sections: | ||||
| 
 | ||||
|  fpc.resptrs:   This section is contained in resptrs.o and always linked to the executable by | ||||
|                 FPC. It containes an exported label fpcrespointers, which is used at runtime | ||||
|                 to find the resptrs section in memory. The resptrs contains pointers to all the | ||||
|                 sections and their sizes. These are updated in a post-precessing step by the | ||||
|                 compiler and by the external resource embedder when applied to an ELF file. | ||||
|                 This section always is 128 Bytes long and initially filled with zeros. | ||||
|                 The first integer (32/64 Bit) value in this section contains the version | ||||
|                 number of the resource system. Currently this value is 1. | ||||
|                 The second integer (32/64 Bit) value in this section contains the number of | ||||
|                 resources. | ||||
|                 After this follows a version-defined number of TFPCResourceSectionInfo entries. | ||||
|  fpc.ressym:    Contains the resource names. This simply is a stream of zero-terminated strings. | ||||
|                 Only textual names are supported, numeric IDs get autoconverted to #ID's. | ||||
|                 The reshash table has got a byte index into ressym to quickly get that data if needed | ||||
|  fpc.reshash:   n TFPCResourceInfo records. (number of entries is defined in fpc.resptrs) | ||||
|  fpc.resdata:   Contains the plain resource data stream. A byte index into the data stream | ||||
|                 is given for each resource entry in TResourceInfo | ||||
|  fpc.resspare:  An empty section which is resized to make room if the size of any of the previous | ||||
|                 sections gets changed. NOT USED IN VERSION 1 (SIZE WILL BE 0) | ||||
|  fpc.resstr:    This section is completely seperated from the rest and contains a block of | ||||
|                 resourcestrings in internal FPC format. | ||||
| 
 | ||||
| resptr TFPCResourceSectionInfo list for FPC resources version 1: | ||||
| 
 | ||||
| Index   Pointer to | ||||
| 0       ressym | ||||
| 1       reshash | ||||
| 2       resdata | ||||
| 3       resspare | ||||
| 4       resstr | ||||
| 5       reserved for future extension (stabs) | ||||
| 6       reserved for future extension | ||||
| } | ||||
| {$ifdef fpc} | ||||
| {$mode objfpc} | ||||
| {$endif} | ||||
| {$H+} | ||||
| unit elfres; | ||||
| 
 | ||||
| interface | ||||
| 
 | ||||
| uses | ||||
|   elfbfd, | ||||
|   SysUtils, | ||||
|   Classes; | ||||
| 
 | ||||
| const fpcres2elf_version=1; | ||||
| 
 | ||||
| // Do not change the following consts, they are dummy tables to generate an .o that makes ld happy | ||||
| const shstrtab = #0+'.symtab'+#0+'.strtab'+#0+'.shstrtab'+#0+'.text'+#0+'.data'+#0+ | ||||
|                  '.bss'+#0+'fpc.ressym'+#0+'fpc.resstr'+#0+'fpc.reshash'+#0+ | ||||
|                  'fpc.resdata'+#0+'fpc.resspare'+#0+#0; | ||||
|       symtab =   #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$01#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$02#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$03#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$04#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$05#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$06#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$07#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$08#$00; | ||||
|       strtab =   #$00#$00; // this actually is just one byte long | ||||
|       zeros  =   #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00; | ||||
|       fake   =   'fakefakefakefakefakefakefakefake'; | ||||
| 
 | ||||
|       // header of a windows 32 bit .res file (16 bytes) | ||||
|       reshdr =   #$00#$00#$00#$00#$20#$00#$00#$00#$FF#$FF#$00#$00#$FF#$FF#$00#$00+ | ||||
|                  #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00; | ||||
| 
 | ||||
|       FilerSignature: array[1..4] of Char = 'TPF0'; | ||||
| 
 | ||||
|       SDefaultExtension = '.or'; | ||||
|        | ||||
| Type | ||||
|   { TElfResCreator } | ||||
| 
 | ||||
|   TElfResCreator = Class(TObject) | ||||
|   private | ||||
|     FDestFileName: String; | ||||
|     FExtension: string; | ||||
|     FSourceFileName: String; | ||||
|     FOverwrite: Boolean; | ||||
|     FVerbose: Boolean; | ||||
|     FVersion: Integer; | ||||
|   Protected | ||||
|     FSectionStream: TMemoryStream; | ||||
|     FDataStream: TMemoryStream; | ||||
|     FSymStream: TMemoryStream; | ||||
|     FHashStream: TMemoryStream; | ||||
|     sectionheader_ofs: integer; | ||||
|     shstrtab_ofs: integer; | ||||
|     CurrentResource:integer; | ||||
|     resheader: string; | ||||
|     Signature: byte; | ||||
|     Procedure AllocateData; virtual; | ||||
|     Procedure FreeData; virtual; | ||||
|     Procedure DoAlign(const a: integer); | ||||
|   Public | ||||
|     Constructor Create; | ||||
|     Procedure Convert(Const Source,Destination : String); | ||||
|     Procedure ConvertStreams(Source,Dest : TStream); | ||||
|     Procedure DoConvertStreams(Source,Dest : TStream); virtual;Abstract; | ||||
|     Property  Verbose : Boolean Read FVerbose Write FVerbose; | ||||
|     Property  SourceFileName : String Read FSourceFileName; | ||||
|     Property  DestFileName : String Read FDestFileName; | ||||
|     Property  Overwrite : Boolean Read FOverwrite Write FOverWrite; | ||||
|     Property  Version : Integer Read FVersion Write FVersion; | ||||
|     Property  Extension : string Read FExtension Write FExtension; | ||||
|   end; | ||||
|    | ||||
|   { TElf32ResCreator } | ||||
| 
 | ||||
|   TElf32ResCreator = Class(TElfResCreator) | ||||
|   Private | ||||
|     ResourceEntries: array of TELF32ResourceInfo; | ||||
|   Protected | ||||
|     Procedure AllocateData; override; | ||||
|     Procedure FreeData; override; | ||||
|   public | ||||
|     procedure LoadBinaryDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
|     procedure LoadTextDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
|     procedure LoadRESEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
|     Procedure DoConvertStreams(Source,Dest : TStream); override; | ||||
|   end; | ||||
|    | ||||
|   { TElf64Creator } | ||||
| 
 | ||||
|   TElf64ResCreator = Class(TElfResCreator) | ||||
|     Procedure DoConvertStreams(Source,Dest : TStream); override; | ||||
|   end; | ||||
| 
 | ||||
|   EElfResError = Class(Exception); | ||||
| 
 | ||||
| implementation | ||||
| 
 | ||||
| resourcestring | ||||
|   SErrUnrecognizedFormat = 'Unrecognized file format for input file "%s"'; | ||||
| 
 | ||||
| Procedure DoError (Msg : String); | ||||
| 
 | ||||
| begin | ||||
|   Raise EElfResError.Create(Msg); | ||||
| end; | ||||
| 
 | ||||
| Procedure DoErrorFmt (Msg : String; Args : Array of const); | ||||
| 
 | ||||
| begin | ||||
|   Raise EElfResError.CreateFmt(Msg,Args); | ||||
| end; | ||||
| 
 | ||||
| function HashELF(const S : string) : longint; | ||||
| {Note: this hash function is described in "Practical Algorithms For | ||||
|        Programmers" by Andrew Binstock and John Rex, Addison Wesley, | ||||
|        with modifications in Dr Dobbs Journal, April 1996} | ||||
| var | ||||
|   G : longint; | ||||
|   i : integer; | ||||
| begin | ||||
|   Result := 0; | ||||
|   for i := 1 to length(S) do begin | ||||
|     Result := (Result shl 4) + ord(S[i]); | ||||
|     G := Result and $F0000000; | ||||
|     if (G <> 0) then | ||||
|       Result := Result xor (G shr 24); | ||||
|     Result := Result and (not G); | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| { TElfResCreator } | ||||
| 
 | ||||
| procedure TElfResCreator.AllocateData; | ||||
| begin | ||||
|   FSectionStream:=TMemoryStream.Create; | ||||
|   FDataStream:=TMemoryStream.Create; | ||||
|   FSymStream:=TMemoryStream.Create; | ||||
|   FHashStream:=TMemoryStream.Create; | ||||
| end; | ||||
| 
 | ||||
| procedure TElfResCreator.FreeData; | ||||
| begin | ||||
|   FreeAndNil(FSectionStream); | ||||
|   FreeAndNil(FDataStream); | ||||
|   FreeAndNil(FSymStream); | ||||
|   FreeAndNil(FHashStream); | ||||
| end; | ||||
| 
 | ||||
| constructor TElfResCreator.Create; | ||||
| begin | ||||
|   FVersion:=fpcres2elf_version; | ||||
|   FOverwrite:=True; | ||||
|   FVerbose:=False; | ||||
|   FExtension:=SDefaultExtension; | ||||
| end; | ||||
| 
 | ||||
| // fill the memorystream so it is aligned, max supported align is 16 | ||||
| procedure TElfResCreator.DoAlign(const a: integer); | ||||
| var i: integer; | ||||
| begin | ||||
|   i:=(4 - (FSectionStream.position MOD a)) MOD a; | ||||
|   if (i>0) then FSectionStream.Write(zeros,i); | ||||
| end; | ||||
| 
 | ||||
| procedure TElfResCreator.Convert(const Source, Destination: String); | ||||
| 
 | ||||
| Var | ||||
|   Src,Dest : TFileStream; | ||||
| 
 | ||||
| begin | ||||
|   FSourceFileName:=Source; | ||||
|   FDestFileName:=Destination; | ||||
|   if FDestFileName='' then | ||||
|     FDestFileName:=ChangeFileExt(Source,FExtension); | ||||
|   Src:=TFileStream.Create(FSourceFileName,fmOpenRead or fmShareDenyWrite); | ||||
|   try | ||||
|     Dest:=TFileStream.Create(FDestFileName,fmCreate or fmShareDenyWrite); | ||||
|     Try | ||||
|       ConvertStreams(Src,Dest); | ||||
|     Finally | ||||
|       Dest.Free; | ||||
|     end; | ||||
|   Finally | ||||
|     Src.Free; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| procedure TElfResCreator.ConvertStreams(Source, Dest: TStream); | ||||
| begin | ||||
|   AllocateData; | ||||
|   Try | ||||
|     DoConvertStreams(Source,Dest); | ||||
|   Finally | ||||
|     FreeData; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| { --------------------------------------------------------------------- | ||||
|   TElf32ResCreator | ||||
|   ---------------------------------------------------------------------} | ||||
| 
 | ||||
| procedure TElf32ResCreator.AllocateData; | ||||
| begin | ||||
|   inherited AllocateData; | ||||
|   // reserve space for 1024 resource entries for now | ||||
|   SetLength(ResourceEntries,1024); | ||||
|   CurrentResource:=0; | ||||
| end; | ||||
| 
 | ||||
| procedure TElf32ResCreator.FreeData; | ||||
| begin | ||||
|   inherited FreeData; | ||||
|   SetLength(ResourceEntries,0); | ||||
| end; | ||||
| 
 | ||||
| procedure TElf32ResCreator.LoadRESEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
| var l:longint; | ||||
|     w:word; | ||||
|     ws:WideString; | ||||
|     wc:WideChar; | ||||
|     name:string; | ||||
|     i: integer; | ||||
|     headersize:integer; | ||||
|     headerstart:integer; | ||||
| begin | ||||
|   headerstart:=rs.Position; | ||||
|   resinfo.ptr:=DataStream.Position; | ||||
|   rs.Read(resinfo.size,4); | ||||
|   rs.Read(headersize,4); | ||||
|   rs.Read(l,4); // Type | ||||
|   if (l AND $0000FFFF)=$0000FFFF then | ||||
|   begin // Type is stored as ID | ||||
|     resinfo.restype:=(l AND $FFFF0000) shr 16; // kill the marker, we always use IDs | ||||
|   end | ||||
|   else | ||||
|   begin | ||||
|     // we don't support text IDs for now, skip until we have reached the end | ||||
|     // of the widestring, and set rcdata (10) in this case. | ||||
|     repeat | ||||
|       rs.Read(w,2); | ||||
|     until w=0; | ||||
|     resinfo.restype:=10; | ||||
|   end; | ||||
| 
 | ||||
|   rs.Read(l,4); // Name | ||||
|   if (l AND $0000FFFF)=$0000FFFF then | ||||
|   begin // Name is stored as ID. | ||||
|     l:=(l AND $FFFF0000) shr 16; // kill the marker | ||||
|     // We don't want to support integer names, we'll instead convert them to a #id string | ||||
|     // which is more common. | ||||
|     name:='#'+inttostr(l); | ||||
|   end | ||||
|   else | ||||
|   begin | ||||
|     // Ok, it's a widestring ID | ||||
|     ws:=widechar(l AND $0000FFFF); | ||||
|     ws:=ws+widechar((l AND $FFFF0000) shr 16); | ||||
|     // get the rest of it | ||||
|     repeat | ||||
|       rs.Read(wc,2); | ||||
|       if wc<>#0 then ws:=ws+wc; | ||||
|     until wc=#0; | ||||
|     // convert to ANSI | ||||
|     name:=ws; | ||||
|   end; | ||||
| 
 | ||||
|   // create a hash of the name | ||||
|   resinfo.reshash:=HashELF(name); | ||||
| 
 | ||||
|   // save the name plus a trailing #0 to the SymStream, also save | ||||
|   // the position of this name in the SymStream | ||||
|   resinfo.name:=SymStream.Position; | ||||
|   name:=name+#0; | ||||
|   SymStream.Write(name[1],length(name)); | ||||
| 
 | ||||
|   // We don't care about the rest of the header | ||||
|   rs.Seek(headersize-(rs.position-headerstart),soFromCurrent); | ||||
| 
 | ||||
|   // Now copy over the resource data into our internal memory stream | ||||
|   DataStream.CopyFrom(rs,resinfo.size); | ||||
| 
 | ||||
|   // Align the resource stream on a dword boundary | ||||
|   i:=(4 - (rs.Position MOD 4)) MOD 4; | ||||
|   if (i>0) then rs.Seek(i,soFromCurrent); | ||||
| 
 | ||||
| 
 | ||||
|   // Align the data stream on a dword boundary | ||||
|   i:=(4 - (DataStream.Position MOD 4)) MOD 4; | ||||
|   if (i>0) then DataStream.Write(zeros,i); | ||||
| end; | ||||
| 
 | ||||
| procedure TElf32ResCreator.LoadBinaryDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
| var name: string; | ||||
|     i: integer; | ||||
| begin | ||||
|   resinfo.ptr:=0; | ||||
|   resinfo.restype:=10; // RCDATA | ||||
| 
 | ||||
|   // Skip the header | ||||
|   rs.Position:=3; | ||||
| 
 | ||||
|   // Read the name | ||||
|   setlength(name,64); // Component names can be 64 chars at max | ||||
|   rs.Read(name[1],64); | ||||
| 
 | ||||
|   // Find end of name | ||||
|   i:=pos(#0,name); | ||||
|   name:=copy(name,1,i-1); | ||||
| 
 | ||||
|   // Seek to after the name and skip other crap | ||||
|   rs.Position:=i+9; | ||||
| 
 | ||||
|   resinfo.size:=rs.Size-rs.Position; | ||||
| 
 | ||||
|   // ...this is followed by the data. | ||||
| 
 | ||||
|   // create a hash of the name | ||||
|   resinfo.reshash:=HashELF(name); | ||||
| 
 | ||||
|   // save the name plus a trailing #0 to the SymStream, also save | ||||
|   // the position of this name in the SymStream | ||||
|   resinfo.name:=SymStream.Position; | ||||
|   name:=name+#0; | ||||
|   SymStream.Write(name[1],length(name)); | ||||
| 
 | ||||
|   // Now copy over the resource data into our internal memory stream | ||||
|   DataStream.CopyFrom(rs,resinfo.size); | ||||
| 
 | ||||
|   // Align the data stream on a dword boundary | ||||
|   i:=(4 - (DataStream.Position MOD 4)) MOD 4; | ||||
|   if (i>0) then DataStream.Write(zeros,i); | ||||
| end; | ||||
| 
 | ||||
| procedure TElf32ResCreator.LoadTextDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo); | ||||
| var ms:TMemoryStream; | ||||
| begin | ||||
|   ms:=nil; | ||||
|   try | ||||
|     ms:=TMemoryStream.Create; | ||||
|     ObjectTextToResource(rs,ms); | ||||
|     LoadBinaryDFMEntry(ms, DataStream, SymStream, resinfo); | ||||
|   finally | ||||
|     ms.free; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| procedure TElf32ResCreator.DoConvertStreams(Source, Dest: TStream); | ||||
| 
 | ||||
| Var | ||||
|   I : Integer; | ||||
|   ElfHeader: TElf32Header; | ||||
|   SectionHeader: TElf32sechdr; | ||||
|   ressym: TELF32ResourceSectionInfo; | ||||
|   resstr: TELF32ResourceSectionInfo; | ||||
|   reshash: TELF32ResourceSectionInfo; | ||||
|   resdata: TELF32ResourceSectionInfo; | ||||
|   resspare: TELF32ResourceSectionInfo; | ||||
|    | ||||
| begin | ||||
|   // Read and check the header of the input file. First check if it's a 32bit resource | ||||
|   // file... | ||||
|   SetLength(resheader,32); | ||||
|   Source.Read(resheader[1],32); | ||||
|   if (resheader<>reshdr) then | ||||
|     begin | ||||
|     // ...not a 32Bit resource file. Now let's see if it's a text or binary dfm/xfm/lfm file. | ||||
|     Source.Position:=0; | ||||
|     Source.Read(Signature,1); | ||||
|     if (Signature=$FF) then | ||||
|       begin | ||||
|       Source.Position:=0; | ||||
|       LoadBinaryDFMEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]); | ||||
|       end | ||||
|     else if char(Signature) in ['o','O','i','I',' ',#13,#11,#9] then | ||||
|       begin | ||||
|       Source.Position:=0; | ||||
|       LoadTextDFMEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]); | ||||
|       end | ||||
|     else | ||||
|       DoErrorFmt(SErrUnrecognizedFormat,[SourceFileName]); | ||||
|     inc(CurrentResource,1); | ||||
|     end | ||||
|   else // ...yes, it's a resource file. | ||||
|     while Source.Position<Source.Size do | ||||
|       begin | ||||
|       // Load Resource info, and copy the resource data into the DataStream | ||||
|       LoadRESEntry(Source, FDataStream, FSymStream, ResourceEntries[CurrentResource]); | ||||
|       inc(CurrentResource,1); | ||||
|       // if we hit the current limit of allocated ResourceEntries in the | ||||
|       // array, allocate some more space | ||||
|       if (CurrentResource>=length(ResourceEntries)) then | ||||
|         setlength(ResourceEntries,length(ResourceEntries)+1024); | ||||
|       end; | ||||
| 
 | ||||
|   // downsize the ResourceEntries to the really needed size | ||||
|   SetLength(ResourceEntries,CurrentResource); | ||||
| 
 | ||||
|   // Write the symbol table - ressym | ||||
|   ressym.ptr:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   FSymStream.Position:=0; | ||||
|   FSectionStream.CopyFrom(FSymStream,FSymStream.Size); | ||||
|   doalign(4); | ||||
| 
 | ||||
|   // resstr | ||||
|   resstr.ptr:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   resstr.size:=0; | ||||
|   // TODO: Load string data here | ||||
|   doalign(4); | ||||
| 
 | ||||
|   // Now write the ResourceInfos. | ||||
|   reshash.ptr:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   for i:=0 to high(ResourceEntries) do | ||||
|   begin | ||||
|     FSectionStream.Write(ResourceEntries[i],sizeof(TELF32ResourceInfo)); | ||||
|   end; | ||||
|   doalign(4); | ||||
| 
 | ||||
|   // Next write the resource data stream | ||||
|   resdata.ptr:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   FDataStream.Position:=0; | ||||
|   FSectionStream.CopyFrom(FDataStream,FDataStream.Size); | ||||
|   doalign(4); | ||||
| 
 | ||||
|   // resspare | ||||
|   resspare.ptr:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   // don't write anything, this is an empty section | ||||
| 
 | ||||
|   // shstrtab - this is not aligned | ||||
|   shstrtab_ofs:=FSectionStream.Position+sizeof(TElf32Header); | ||||
|   FSectionStream.Write(shstrtab,length(shstrtab)); | ||||
| 
 | ||||
|   // Write 12 section headers. The headers itself don't need to be aligned, | ||||
|   // as their size can be divided by 4. As shstrtab is uneven and not aligned, | ||||
|   // we however need to align the start of the section header table | ||||
|   doalign(4); | ||||
|   sectionheader_ofs:=FSectionStream.Position+sizeof(TElf32Header);; | ||||
| 
 | ||||
|   // empty one | ||||
|   fillchar(SectionHeader,sizeof(SectionHeader),0); | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .text | ||||
|   SectionHeader.sh_name:=$1B; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=6; // AX | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0 | ||||
|   SectionHeader.sh_size:=0; // yep, pretty empty it is | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .data | ||||
|   SectionHeader.sh_name:=$21; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=3; // WA | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0 | ||||
|   SectionHeader.sh_size:=0; // yep, pretty empty it is | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .bss | ||||
|   SectionHeader.sh_name:=$27; | ||||
|   SectionHeader.sh_type:=8; // NOBITS | ||||
|   SectionHeader.sh_flags:=3; // WA | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0 | ||||
|   SectionHeader.sh_size:=0; // yep, pretty empty it is | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // fpc.ressym | ||||
|   SectionHeader.sh_name:=$2C; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=2; // A | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=ressym.ptr; // directly after header | ||||
|   SectionHeader.sh_size:=FSymStream.Size; | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // fpc.resstr | ||||
|   SectionHeader.sh_name:=$37; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=2; // A | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=resstr.ptr; | ||||
|   SectionHeader.sh_size:=0; // currently empty | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // fpc.reshash | ||||
|   SectionHeader.sh_name:=$42; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=2; // A | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=reshash.ptr; | ||||
|   SectionHeader.sh_size:=length(ResourceEntries)*sizeof(TELF32ResourceInfo)+4; | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // fpc.resdata | ||||
|   SectionHeader.sh_name:=$4e; | ||||
|   SectionHeader.sh_type:=1; // PROGBITS | ||||
|   SectionHeader.sh_flags:=2; // A | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=resdata.ptr; | ||||
|   SectionHeader.sh_size:=FDataStream.Size; | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // fpc.resspare | ||||
|   // Not used in V1 | ||||
|   SectionHeader.sh_name:=$5a; | ||||
|   SectionHeader.sh_type:=8; // NOBITS | ||||
|   SectionHeader.sh_flags:=2; // A | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=resspare.ptr; // fake, as it's empty, should be equal to shstrtab's offset | ||||
|   SectionHeader.sh_size:=0; //DataStream.Size; // Leave as much room as we currently have in resdata section | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .shstrtab | ||||
|   SectionHeader.sh_name:=$11; | ||||
|   SectionHeader.sh_type:=3; // STRTAB | ||||
|   SectionHeader.sh_flags:=0; | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=shstrtab_ofs;  // $3E | ||||
|   SectionHeader.sh_size:=$67; | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=1; // alignment | ||||
|   SectionHeader.sh_entsize:=0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .symtab | ||||
|   SectionHeader.sh_name:=$01; | ||||
|   SectionHeader.sh_type:=2; // SYMTAB | ||||
|   SectionHeader.sh_flags:=0; | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+sizeOf(SectionHeader); // will come directly after this and the next section. $0288; | ||||
|   SectionHeader.sh_size:=$90; | ||||
|   SectionHeader.sh_link:=$0B; | ||||
|   SectionHeader.sh_info:=$09; | ||||
|   SectionHeader.sh_addralign:=4; // alignment | ||||
|   SectionHeader.sh_entsize:=$10; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // .strtab | ||||
|   SectionHeader.sh_name:=$09; | ||||
|   SectionHeader.sh_type:=3; // STRTAB | ||||
|   SectionHeader.sh_flags:=0; | ||||
|   SectionHeader.sh_addr:=0; | ||||
|   SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+$90; // will come after this sectionheader and the $90 bytes symtab - $0318; end of file | ||||
|   SectionHeader.sh_size:=1; | ||||
|   SectionHeader.sh_link:=0; | ||||
|   SectionHeader.sh_info:=0; | ||||
|   SectionHeader.sh_addralign:=1; // alignment | ||||
|   SectionHeader.sh_entsize:=$0; | ||||
|   FSectionStream.Write(SectionHeader,sizeOf(SectionHeader)); | ||||
| 
 | ||||
|   // now write the symbol table | ||||
|   FSectionStream.Write(symtab,length(symtab)); | ||||
|   // We don't need to align it, as it's $90 in size | ||||
| 
 | ||||
|   // now write the string table, it's just a single byte | ||||
|   FSectionStream.Write(strtab,1); | ||||
| 
 | ||||
|   // Ok, we are done, now let's really write something to disk... | ||||
| 
 | ||||
|   // First write the ELF header | ||||
| 
 | ||||
|   fillchar(ElfHeader,sizeof(ElfHeader),0); | ||||
|   ElfHeader.magic0123:=$464c457f; { = #127'ELF' } | ||||
|   ElfHeader.file_class:=1; | ||||
|   ElfHeader.data_encoding:=1; | ||||
|   ElfHeader.file_version:=1; | ||||
|   ElfHeader.e_type:=1; | ||||
|   ElfHeader.e_machine:=3; | ||||
|   ElfHeader.e_version:=1; | ||||
|   ElfHeader.e_shoff:=sectionheader_ofs; | ||||
|   ElfHeader.e_shstrndx:=9; | ||||
|   ElfHeader.e_shnum:=12; | ||||
|   ElfHeader.e_ehsize:=sizeof(TElf32header); | ||||
|   ElfHeader.e_shentsize:=sizeof(TElf32sechdr); | ||||
| 
 | ||||
|   Dest.Write(ElfHeader,sizeof(TElf32header)); | ||||
| 
 | ||||
|   // And now let's dump our whole memorystream into it. | ||||
|   Dest.CopyFrom(FSectionStream,0); | ||||
| end; | ||||
| 
 | ||||
| 
 | ||||
| { TElf64Creator } | ||||
| 
 | ||||
| procedure TElf64ResCreator.DoConvertStreams(Source, Dest: TStream); | ||||
| begin | ||||
|   DoError('64 bits resources not yet supported') | ||||
| end; | ||||
| 
 | ||||
| end. | ||||
							
								
								
									
										260
									
								
								utils/fpcres/elfresfix.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								utils/fpcres/elfresfix.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,260 @@ | ||||
| 
 | ||||
| { *********************************************************************** } | ||||
| {                                                                         } | ||||
| {  elfresfix - Free Pascal Resource to ELF object compiler - fixup tool   } | ||||
| {  Part of the Free Pascal and CrossFPC distributions                     } | ||||
| {                                                                         } | ||||
| {  Copyright (C) 2005 Simon Kissel                                        } | ||||
| {                                                                         } | ||||
| {  See the file COPYING.FPC, included in the FPC distribution,            } | ||||
| {  for details about the copyright.                                       } | ||||
| {                                                                         } | ||||
| {  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.                   } | ||||
| {                                                                         } | ||||
| { *********************************************************************** } | ||||
| 
 | ||||
| { | ||||
| This tool will update the fpc.resptrs section of an ELF executable to point | ||||
| to the various resource sections in the file. This is done so that the FPC | ||||
| RTL at runtime is able to get pointers to these sections. | ||||
| 
 | ||||
| This tool is automatically run on any fpc compiled ELF executable that | ||||
| contains ELF resources. | ||||
| 
 | ||||
| fpcresfix builds with Delphi, Kylix and FPC. | ||||
| 
 | ||||
| Currently this only works on 32Bit targets, but support for 64Bit targets | ||||
| is in the works. Support for big endian systems is completely missing, | ||||
| though. | ||||
| } | ||||
| {$ifdef fpc} | ||||
| {$mode objfpc} | ||||
| {$endif} | ||||
| {$h+} | ||||
| 
 | ||||
| unit elfresfix; | ||||
| 
 | ||||
| interface | ||||
| 
 | ||||
| uses | ||||
|   SysUtils, Classes, elfbfd; | ||||
|    | ||||
| Type | ||||
| 
 | ||||
|   TLogEvent = Procedure(Const Msg : String) of object; | ||||
|    | ||||
|   { TElfResourceFixer } | ||||
| 
 | ||||
|   TElfResourceFixer = Class(TObject) | ||||
|   private | ||||
|     FFileName: String; | ||||
|     FOnVerbose: TLogEvent; | ||||
|     FVerbose: Boolean; | ||||
|     Procedure DoVerbose(Msg : String); | ||||
|   public | ||||
|     Procedure FixFile(AFileName : String); | ||||
|     Procedure DoFixStream(Stream : TStream); virtual; abstract; | ||||
|     Property Verbose : Boolean read FVerbose write FVerbose; | ||||
|     Property FileName : String Read FFileName; | ||||
|     Property Onverbose : TLogEvent Read FOnVerbose Write FOnVerbose; | ||||
|   end; | ||||
|    | ||||
|   { TElf32ResourceFixer } | ||||
| 
 | ||||
|   TElf32ResourceFixer = Class(TElfResourceFixer) | ||||
|     Procedure DoFixStream(Stream : TStream); override; | ||||
|   end; | ||||
|    | ||||
|   { TElf64ResourceFixer } | ||||
| 
 | ||||
|   TElf64ResourceFixer = Class(TElfResourceFixer) | ||||
|     Procedure DoFixStream(Stream : TStream); override; | ||||
|   end; | ||||
| 
 | ||||
|   EElfResFixError = Class(Exception); | ||||
| 
 | ||||
| Implementation | ||||
| 
 | ||||
| ResourceString | ||||
|   SCheckingHeader           = 'Checking ELF Header... '; | ||||
|   SReadingSectionHeaders    = 'Reading Section Headers...'; | ||||
|   SHeaderOK                 = 'ELF Header is OK'; | ||||
|   SCheckingHeaderTable      = 'Checking Section Header table...'; | ||||
|   SStrTabFound              = 'Found strtab...'; | ||||
|   SProcessingSection        = 'Processing section: '; | ||||
|   SUpdatingResptrs          = 'Updating resptrs section...'; | ||||
|   SFileFixed                = 'File fixed successfully!'; | ||||
|   SNothingToFix             = 'There was nothing to fix in this file.'; | ||||
|    | ||||
|   SErrUnsupportedHeaderSize = 'Unsupported Section Header size.'; | ||||
|   SErrInvalidELFHeader      = 'Not a valid linux ELF binary.'; | ||||
|   SErrResPtrsNotFound       = 'Unable to find resptrs section.'; | ||||
|    | ||||
| Procedure DoError (Msg : String); | ||||
| 
 | ||||
| begin | ||||
|   Raise EElfResFixError.Create(Msg); | ||||
| end; | ||||
| 
 | ||||
| Procedure DoErrorFmt (Msg : String; Args : Array of const); | ||||
| 
 | ||||
| begin | ||||
|   Raise EElfResFixError.CreateFmt(Msg,Args); | ||||
| end; | ||||
| 
 | ||||
| { TElfResourceFixer } | ||||
| 
 | ||||
| procedure TElfResourceFixer.DoVerbose(Msg: String); | ||||
| begin | ||||
|   If FVerbose and Assigned(FOnVerbose) then | ||||
|     FOnVerbose(Msg); | ||||
| end; | ||||
| 
 | ||||
| procedure TElfResourceFixer.FixFile(AFileName: String); | ||||
| 
 | ||||
| Var | ||||
|   F : TStream; | ||||
| 
 | ||||
| begin | ||||
|   FFileName:=AFileName; | ||||
|   F:=TFileStream.Create(AFilename,fmOpenReadWrite or fmShareDenyWrite); | ||||
|   Try | ||||
|     DoFixStream(F); | ||||
|   Finally | ||||
|     F.Free; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| { TElf32ResourceFixer } | ||||
| 
 | ||||
| procedure TElf32ResourceFixer.DoFixStream(Stream: TStream); | ||||
| 
 | ||||
| var | ||||
|   ElfHeader:TElf32header; | ||||
|   ResourceSectionTable: TElf32ResourceSectionTable; | ||||
|   SectionHeaders: array of TElf32sechdr; | ||||
| 
 | ||||
|   i:integer; | ||||
|   sn:string; | ||||
|   SectionHeaderOffset:integer; | ||||
|   fixed: boolean; | ||||
|   strtab:string; | ||||
|   SectionName: string; | ||||
|   ResPtrsSection: integer; | ||||
| 
 | ||||
| begin | ||||
|   Fixed:=False; | ||||
|   Stream.Read(ElfHeader,sizeof(TElf32header)); | ||||
|   DoVerbose(SCheckingHeader); | ||||
|   if (ElfHeader.magic0123<>$464C457F) then | ||||
|     DoError(SErrInvalidELFheader); | ||||
|   if ElfHeader.e_shentsize=sizeof(TElf32sechdr) then | ||||
|     DoVerbose(SHeaderOK) | ||||
|   else | ||||
|     DoError(SErrUnSupportedHeaderSize); | ||||
|   DoVerbose(SReadingSectionHeaders); | ||||
| 
 | ||||
|   setlength(SectionHeaders,ElfHeader.e_shnum); | ||||
|   SectionHeaderOffset:=ElfHeader.e_shoff; | ||||
|   Stream.Position:=SectionHeaderOffset; | ||||
| 
 | ||||
|   for i:=0 to ElfHeader.e_shnum-1 do | ||||
|     begin | ||||
|     Stream.Read(SectionHeaders[i],sizeof(TElf32sechdr)); | ||||
|     end; | ||||
| 
 | ||||
|   DoVerbose(SCheckingHeaderTable); | ||||
| 
 | ||||
|   // Get the section header strtab | ||||
|   i:=ElfHeader.e_shstrndx; | ||||
|   if SectionHeaders[i].sh_type=SHT_STRTAB then | ||||
|     begin | ||||
|     DoVerbose(SStrTabFound); | ||||
|     // read the strtab | ||||
|     Stream.Position:=SectionHeaders[i].sh_offset; | ||||
|     setlength(strtab,SectionHeaders[i].sh_size); | ||||
|     Stream.Read(strtab[1],SectionHeaders[i].sh_size); | ||||
|   end | ||||
|   else | ||||
|   begin | ||||
|     writeln('Error: Unable to find strtab.'); | ||||
|     halt(5); | ||||
|   end; | ||||
| 
 | ||||
|   ResPtrsSection:=-1; | ||||
|   ResourceSectionTable.version:=66; | ||||
| 
 | ||||
|   // Next cycle through all sections to gather pointers to all the resource | ||||
|   // sections, and note the index of the resptrs section | ||||
|   for i:=0 to ElfHeader.e_shnum-1 do | ||||
|     begin | ||||
|     SectionName:=copy(strtab,SectionHeaders[i].sh_name+1,32); | ||||
|     SectionName:=copy(SectionName,1,pos(#0,SectionName)-1); | ||||
|     DoVerbose(SProcessingSection+SectionName); | ||||
|     sn:=Copy(SectionName,1,4); | ||||
|     // FPC section ? | ||||
|     if (sn='fpc.') then | ||||
|       begin | ||||
|       sn:=SectionName; | ||||
|       Delete(SN,1,4); | ||||
|       if SN='resptrs' then | ||||
|         begin | ||||
|         ResPtrsSection:=i; | ||||
|         end | ||||
|       else if sn='ressym' then | ||||
|         begin | ||||
|         ResourceSectionTable.ressym.ptr:=SectionHeaders[i].sh_addr; | ||||
|         ResourceSectionTable.ressym.size:=SectionHeaders[i].sh_size; | ||||
|         end | ||||
|       else if sn='reshash' then | ||||
|         begin | ||||
|         ResourceSectionTable.reshash.ptr:=SectionHeaders[i].sh_addr; | ||||
|         ResourceSectionTable.reshash.size:=SectionHeaders[i].sh_size; | ||||
|         ResourceSectionTable.resentries:=SectionHeaders[i].sh_size DIV sizeof(TELF32ResourceInfo); | ||||
|         end | ||||
|       else if sn='resdata' then | ||||
|         begin | ||||
|         ResourceSectionTable.resdata.ptr:=SectionHeaders[i].sh_addr; | ||||
|         ResourceSectionTable.resdata.size:=SectionHeaders[i].sh_size; | ||||
|         end | ||||
|       else if sn='resspare' then | ||||
|         begin | ||||
|         ResourceSectionTable.resspare.ptr:=SectionHeaders[i].sh_addr; | ||||
|         ResourceSectionTable.resspare.size:=SectionHeaders[i].sh_size; | ||||
|         end | ||||
|       else if SectionName='resstr' then | ||||
|         begin | ||||
|         ResourceSectionTable.resstr.ptr:=SectionHeaders[i].sh_addr; | ||||
|         ResourceSectionTable.resstr.size:=SectionHeaders[i].sh_size; | ||||
|         end; | ||||
|       end | ||||
|   end; | ||||
| 
 | ||||
|   // Ok, we now have pointers to all resource sections and also | ||||
|   // know the number of resources. | ||||
|   // Now update the resptrs table | ||||
|   if ResPtrsSection>-1 then | ||||
|     begin | ||||
|     Doverbose(SUpdatingResPtrs); | ||||
|     Stream.Position:=SectionHeaders[ResPtrsSection].sh_offset; | ||||
|     Stream.Write(ResourceSectionTable,sizeof(TELF32ResourceSectionTable)); | ||||
|     fixed:=true; | ||||
|     end | ||||
|   else | ||||
|     DoError(SErrREsptrsNotFound); | ||||
|   if fixed then | ||||
|     DoVerbose(SFileFixed) | ||||
|   else | ||||
|     writeln(SNothingToFix); | ||||
| end; | ||||
| 
 | ||||
| { TElf64ResourceFixer } | ||||
| 
 | ||||
| procedure TElf64ResourceFixer.DoFixStream(Stream: TStream); | ||||
| begin | ||||
|   DoError('64-bit resources not yet supported'); | ||||
| end; | ||||
| 
 | ||||
| end. | ||||
							
								
								
									
										171
									
								
								utils/fpcres/fpcres.lpi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								utils/fpcres/fpcres.lpi
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,171 @@ | ||||
| <?xml version="1.0"?> | ||||
| <CONFIG> | ||||
|   <ProjectOptions> | ||||
|     <PathDelim Value="/"/> | ||||
|     <Version Value="5"/> | ||||
|     <General> | ||||
|       <Flags> | ||||
|         <MainUnitHasUsesSectionForAllUnits Value="False"/> | ||||
|         <MainUnitHasCreateFormStatements Value="False"/> | ||||
|         <MainUnitHasTitleStatement Value="False"/> | ||||
|       </Flags> | ||||
|       <MainUnit Value="0"/> | ||||
|       <ActiveEditorIndexAtStart Value="0"/> | ||||
|       <IconPath Value="./"/> | ||||
|       <TargetFileExt Value=""/> | ||||
|     </General> | ||||
|     <JumpHistory Count="18" HistoryIndex="17"> | ||||
|       <Position1> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="175" Column="14" TopLine="138"/> | ||||
|       </Position1> | ||||
|       <Position2> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="144" Column="11" TopLine="122"/> | ||||
|       </Position2> | ||||
|       <Position3> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="143" Column="5" TopLine="122"/> | ||||
|       </Position3> | ||||
|       <Position4> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="148" Column="29" TopLine="126"/> | ||||
|       </Position4> | ||||
|       <Position5> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="152" Column="5" TopLine="130"/> | ||||
|       </Position5> | ||||
|       <Position6> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="162" Column="8" TopLine="140"/> | ||||
|       </Position6> | ||||
|       <Position7> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="162" Column="8" TopLine="140"/> | ||||
|       </Position7> | ||||
|       <Position8> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="163" Column="3" TopLine="141"/> | ||||
|       </Position8> | ||||
|       <Position9> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="162" Column="34" TopLine="141"/> | ||||
|       </Position9> | ||||
|       <Position10> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="170" Column="25" TopLine="148"/> | ||||
|       </Position10> | ||||
|       <Position11> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="170" Column="25" TopLine="148"/> | ||||
|       </Position11> | ||||
|       <Position12> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="170" Column="25" TopLine="148"/> | ||||
|       </Position12> | ||||
|       <Position13> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="148" Column="17" TopLine="148"/> | ||||
|       </Position13> | ||||
|       <Position14> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="67" Column="16" TopLine="67"/> | ||||
|       </Position14> | ||||
|       <Position15> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="70" Column="1" TopLine="28"/> | ||||
|       </Position15> | ||||
|       <Position16> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="233" Column="27" TopLine="190"/> | ||||
|       </Position16> | ||||
|       <Position17> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="143" Column="5" TopLine="121"/> | ||||
|       </Position17> | ||||
|       <Position18> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <Caret Line="137" Column="1" TopLine="137"/> | ||||
|       </Position18> | ||||
|     </JumpHistory> | ||||
|     <Units Count="5"> | ||||
|       <Unit0> | ||||
|         <CursorPos X="18" Y="4"/> | ||||
|         <EditorIndex Value="0"/> | ||||
|         <Filename Value="fpcres.pas"/> | ||||
|         <IsPartOfProject Value="True"/> | ||||
|         <Loaded Value="True"/> | ||||
|         <TopLine Value="1"/> | ||||
|         <UnitName Value="fpcres"/> | ||||
|         <UsageCount Value="32"/> | ||||
|       </Unit0> | ||||
|       <Unit1> | ||||
|         <CursorPos X="1" Y="235"/> | ||||
|         <EditorIndex Value="1"/> | ||||
|         <Filename Value="elfres.pas"/> | ||||
|         <IsPartOfProject Value="True"/> | ||||
|         <Loaded Value="True"/> | ||||
|         <TopLine Value="206"/> | ||||
|         <UnitName Value="elfres"/> | ||||
|         <UsageCount Value="32"/> | ||||
|       </Unit1> | ||||
|       <Unit2> | ||||
|         <CursorPos X="1" Y="1"/> | ||||
|         <Filename Value="/home/michael/cmdline.pp"/> | ||||
|         <TopLine Value="1"/> | ||||
|         <UsageCount Value="10"/> | ||||
|       </Unit2> | ||||
|       <Unit3> | ||||
|         <CursorPos X="1" Y="1"/> | ||||
|         <EditorIndex Value="3"/> | ||||
|         <Filename Value="elfbfd.pas"/> | ||||
|         <IsPartOfProject Value="True"/> | ||||
|         <Loaded Value="True"/> | ||||
|         <TopLine Value="1"/> | ||||
|         <UnitName Value="elfbfd"/> | ||||
|         <UsageCount Value="25"/> | ||||
|       </Unit3> | ||||
|       <Unit4> | ||||
|         <CursorPos X="1" Y="121"/> | ||||
|         <EditorIndex Value="2"/> | ||||
|         <Filename Value="elfresfix.pas"/> | ||||
|         <IsPartOfProject Value="True"/> | ||||
|         <Loaded Value="True"/> | ||||
|         <TopLine Value="109"/> | ||||
|         <UnitName Value="elfresfix"/> | ||||
|         <UsageCount Value="25"/> | ||||
|       </Unit4> | ||||
|     </Units> | ||||
|     <PublishOptions> | ||||
|       <Version Value="2"/> | ||||
|       <IgnoreBinaries Value="False"/> | ||||
|       <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> | ||||
|       <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> | ||||
|     </PublishOptions> | ||||
|     <RunParams> | ||||
|       <local> | ||||
|         <FormatVersion Value="1"/> | ||||
|         <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> | ||||
|       </local> | ||||
|     </RunParams> | ||||
|   </ProjectOptions> | ||||
|   <CompilerOptions> | ||||
|     <Version Value="5"/> | ||||
|     <CodeGeneration> | ||||
|       <Generate Value="Faster"/> | ||||
|     </CodeGeneration> | ||||
|     <Other> | ||||
|       <CompilerPath Value="$(CompPath)"/> | ||||
|     </Other> | ||||
|   </CompilerOptions> | ||||
|   <Debugging> | ||||
|     <Exceptions Count="2"> | ||||
|       <Item1> | ||||
|         <Name Value="ECodetoolError"/> | ||||
|       </Item1> | ||||
|       <Item2> | ||||
|         <Name Value="EFOpenError"/> | ||||
|       </Item2> | ||||
|     </Exceptions> | ||||
|   </Debugging> | ||||
| </CONFIG> | ||||
							
								
								
									
										277
									
								
								utils/fpcres/fpcres.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								utils/fpcres/fpcres.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,277 @@ | ||||
| {$ifdef fpc} | ||||
| {$mode objfpc} | ||||
| {$endif} | ||||
| {$apptype console} | ||||
| {$H+} | ||||
| program fpcres; | ||||
| 
 | ||||
| uses | ||||
|   Classes, SysUtils, elfres, elfresfix; | ||||
| 
 | ||||
| resourcestring | ||||
|   SError           = 'Error:'; | ||||
|   SErrUnknownParam = 'Unknown command-line parameter : %s'; | ||||
|   SErrNeedArgument = 'Option at pos %d (%s) needs an argument.'; | ||||
|   SErrNoInputFile  = 'No input filename was specified'; | ||||
|   SErrNoOutputFile = 'Outputfile is not allowed when multiple input files are given'; | ||||
|   SErrOutputFileIllegal = 'Outputfile not allowed when fixing headers.'; | ||||
| 
 | ||||
|   SUsage010 = 'fpcres - Free Pascal Resource to ELF object compiler'; | ||||
|   SUsage020 = 'Part of the Free Pascal and CrossFPC distributions'; | ||||
|   SUsage030 = 'Copyright (C) 2005 Simon Kissel'; | ||||
|   SUsage040 = '--------------------------------------------------------'; | ||||
|   SUsage050 = 'Usage: fpcres [options] -i inputfile [-i inputfile] [-o outputfile]'; | ||||
|   SUsage055 = ' where options are one or more of:'; | ||||
|   SUsage060 = ' -i --input=inputfile'; | ||||
|   SUsage065 = '                   A file in windows .res resource format, '; | ||||
|   SUsage070 = '                   or a Delphi/Kylix form file in dfm/xfm  '; | ||||
|   SUsage080 = '                   format (binary or text).'; | ||||
|   SUSage085 = '                   More than one inputfile may be specified.'; | ||||
|   SUsage090 = ' -o --output=outputfile'; | ||||
|   SUsage095 = '                   Name of the object file to generate. If '; | ||||
|   SUsage100 = '                   omitted, the name of the input file will'; | ||||
|   SUsage110 = '                   be used, with .or as extension.'; | ||||
|   SUSage115 = '                   (not allowed with multiple input files.)'; | ||||
|   SUsage116 = ' -e --extension=ext'; | ||||
|   SUsage117 = '                   use ext as the extension for output filenames'; | ||||
|   SUsage120 = ' -h --help         show this help message.'; | ||||
|   SUsage130 = ' -f --fixheader    fix resource block header.'; | ||||
|   SUsage140 = ' -6 --64bit        Use 64-bit elf resources.'; | ||||
|   SUsage150 = ' -v --verbose      be verbose.'; | ||||
| 
 | ||||
| 
 | ||||
| Type | ||||
|   TRunMode = (rmCreateElfRes,rmFixHeader); | ||||
| 
 | ||||
| Var | ||||
|   RunMode        : TRunMode; | ||||
|   InputFiles     : TStringList; | ||||
|   OutputFileName : String; | ||||
|   Use64bit       : Boolean; | ||||
|   BeVerbose      : Boolean; | ||||
|   UseExt         : String; | ||||
| 
 | ||||
| Procedure Usage(ExitStatus : Word); | ||||
| 
 | ||||
| begin | ||||
|   Writeln(SUsage010); | ||||
|   Writeln(SUsage020); | ||||
|   Writeln(SUsage030); | ||||
|   Writeln(SUsage040); | ||||
|   Writeln(SUsage050); | ||||
|   Writeln(SUsage055); | ||||
|   Writeln(SUsage060); | ||||
|   Writeln(SUsage065); | ||||
|   Writeln(SUsage070); | ||||
|   Writeln(SUsage080); | ||||
|   Writeln(SUSage085); | ||||
|   Writeln(SUsage090); | ||||
|   Writeln(SUsage095); | ||||
|   Writeln(SUsage100); | ||||
|   Writeln(SUsage110); | ||||
|   Writeln(SUSage115); | ||||
|   Writeln(SUSage116); | ||||
|   Writeln(SUSage117); | ||||
|   Writeln(SUsage120); | ||||
|   Writeln(SUsage130); | ||||
|   Writeln(SUsage140); | ||||
|   Writeln(SUsage150); | ||||
|   Halt(ExitStatus); | ||||
| end; | ||||
| 
 | ||||
| Procedure DoError(Msg : String; Args : Array of const); | ||||
| 
 | ||||
| begin | ||||
|   Writeln(SError,' ',Format(Msg,Args)); | ||||
|   Usage(1); | ||||
| end; | ||||
| 
 | ||||
| Procedure AnalyzeParams; | ||||
| 
 | ||||
|   Function CheckOption(Index : Integer;Short,Long : String): Boolean; | ||||
| 
 | ||||
|   var | ||||
|     O : String; | ||||
| 
 | ||||
|   begin | ||||
|     O:=Paramstr(Index); | ||||
|     Result:=(O='-'+short) or (copy(O,1,Length(Long)+3)=('--'+long+'=')); | ||||
|   end; | ||||
| 
 | ||||
|   Function OptionArg(Var Index : Integer) : String; | ||||
| 
 | ||||
|   Var | ||||
|     P : Integer; | ||||
| 
 | ||||
|   begin | ||||
|     if (Length(ParamStr(Index))>1) and (Paramstr(Index)[2]<>'-') then | ||||
|       begin | ||||
|       If Index<ParamCount then | ||||
|         begin | ||||
|         Inc(Index); | ||||
|         Result:=Paramstr(Index); | ||||
|         end | ||||
|       else | ||||
|         DoError(SErrNeedArgument,[Index,ParamStr(Index)]); | ||||
|       end | ||||
|     else If length(ParamStr(Index))>2 then | ||||
|       begin | ||||
|       P:=Pos('=',Paramstr(Index)); | ||||
|       If (P=0) then | ||||
|         DoError(SErrNeedArgument,[Index,ParamStr(Index)]) | ||||
|       else | ||||
|         begin | ||||
|         Result:=Paramstr(Index); | ||||
|         Delete(Result,1,P); | ||||
|         end; | ||||
|       end; | ||||
|   end; | ||||
| 
 | ||||
| Var | ||||
|   I : Integer; | ||||
|   P : String; | ||||
|    | ||||
| begin | ||||
|   RunMode:=rmCreateElfres; | ||||
|   Use64bit:=False; | ||||
|   BeVerbose:=False; | ||||
|   I:=0; | ||||
|   While (I<ParamCount) do | ||||
|     begin | ||||
|     Inc(I); | ||||
|     // Values. | ||||
|     If Checkoption(I,'o','output') then | ||||
|       OutPutFileName:=OptionArg(I) | ||||
|     else if Checkoption(I,'i','input') then | ||||
|       InputFiles.Add(OptionArg(I)) | ||||
|     else If Checkoption(I,'e','extension') then | ||||
|       UseExt:=OptionArg(I) | ||||
|     else if CheckOption(I,'f','fixheader') then | ||||
|       RunMode:=rmFixHeader | ||||
|     else if CheckOption(I,'6','64bit') then | ||||
|       Use64bit:=True | ||||
|     else if CheckOption(I,'h','help') then | ||||
|       Usage(0) | ||||
|     else if CheckOption(I,'v','verbose') then | ||||
|       BeVerbose:=True | ||||
|     else | ||||
|       begin | ||||
|       P:=ParamStr(I); | ||||
|       if (Length(P)>0) and (P[1]<>'-') then | ||||
|         begin | ||||
|         if (I=ParamCount) then | ||||
|           OutputFileName:=P | ||||
|         else | ||||
|           InputFiles.Add(P) | ||||
|         end | ||||
|       else | ||||
|         begin | ||||
|         DoError(SErrUnknownParam,[P]); | ||||
|         Usage(1); | ||||
|         end; | ||||
|       end; | ||||
|     end; | ||||
|   If (InputFiles.Count=0) then | ||||
|     DoError(SErrNoInputFile,[]); | ||||
|   If (InputFiles.Count>1) and (OutputFileName<>'') then | ||||
|     DoError(SErrNoOutputFile,[]); | ||||
|   If (RunMode=rmFixHeader) and (OutputFileName<>'') then | ||||
|     DoError(SErrOutputFileIllegal,[]) | ||||
| end; | ||||
| 
 | ||||
| Type | ||||
|   TLogger = Class(TObject) | ||||
|     Procedure Log(Const Msg : String); | ||||
|   end; | ||||
| 
 | ||||
| Procedure TLogger.Log(Const Msg : string); | ||||
| 
 | ||||
| begin | ||||
|   Writeln(Msg); | ||||
| end; | ||||
| 
 | ||||
| Procedure FixHeader(AFileName : String); | ||||
| 
 | ||||
| Var | ||||
|   F : TElfResourceFixer; | ||||
|   O : TLogger; | ||||
|    | ||||
| begin | ||||
|   if Use64bit then | ||||
|     F:=TElf64ResourceFixer.Create | ||||
|   else | ||||
|     F:=TElf32ResourceFixer.Create; | ||||
|   try | ||||
|     F.Verbose:=BeVerbose; | ||||
|     if BeVerbose then | ||||
|       begin | ||||
|       O:=TLogger.Create; | ||||
|       F.OnVerbose:={$ifdef fpc}@{$endif}O.Log; | ||||
|       end | ||||
|     else | ||||
|       O:=Nil; | ||||
|     Try | ||||
|       F.FixFile(AFileName); | ||||
|     Finally | ||||
|       O.Free; | ||||
|     end; | ||||
|   Finally | ||||
|     F.Free; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| Procedure CreateRes(AFileName : String); | ||||
| 
 | ||||
| Var | ||||
|   C : TElfResCreator; | ||||
| 
 | ||||
| begin | ||||
|   If Use64Bit then | ||||
|     C:=TElf64ResCreator.Create | ||||
|   else | ||||
|     C:=TElf32ResCreator.Create; | ||||
|   With C do | ||||
|     Try | ||||
|       Verbose:=BeVerbose; | ||||
|       If (UseExt<>'') then | ||||
|         Extension:=UseExt; | ||||
|       Convert(AFileName,OutputFileName); | ||||
|     Finally | ||||
|       Free; | ||||
|     end; | ||||
| end; | ||||
| 
 | ||||
| Procedure Run; | ||||
| 
 | ||||
| Var | ||||
|   I : Integer; | ||||
|    | ||||
| begin | ||||
|   Try | ||||
|     Case RunMode of | ||||
|       rmFixHeader: | ||||
|         For I:=0 to InputFiles.Count-1 do | ||||
|           FixHeader(InputFiles[i]); | ||||
|       rmCreateElfRes: | ||||
|         For I:=0 to InputFiles.Count-1 do | ||||
|           CreateRes(InputFiles[i]); | ||||
|     end; | ||||
|   except | ||||
|     On E : Exception do | ||||
|       begin | ||||
|       Writeln(SError,' ',E.Message); | ||||
|       Halt(1); | ||||
|       end; | ||||
|   end; | ||||
| end; | ||||
| 
 | ||||
| begin | ||||
|   InputFiles:=TStringList.Create; | ||||
|   Try | ||||
|     AnalyzeParams; | ||||
|     Run; | ||||
|   Finally | ||||
|     FreeAndNil(InputFiles); | ||||
|   end; | ||||
| end. | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 michael
						michael