55namespace SPC \builder \linux ;
66
77use SPC \builder \unix \UnixBuilderBase ;
8+ use SPC \exception \PatchException ;
89use SPC \exception \WrongUsageException ;
910use SPC \store \Config ;
1011use SPC \store \FileSystem ;
@@ -193,7 +194,7 @@ protected function buildCli(): void
193194 SourcePatcher::patchFile ('musl_static_readline.patch ' , SOURCE_PATH . '/php-src ' , true );
194195 }
195196
196- $ this ->deployBinary (BUILD_TARGET_CLI );
197+ $ this ->deploySAPIBinary (BUILD_TARGET_CLI );
197198 }
198199
199200 protected function buildCgi (): void
@@ -204,7 +205,7 @@ protected function buildCgi(): void
204205 ->exec ('sed -i "s|//lib|/lib|g" Makefile ' )
205206 ->exec ("make {$ concurrency } {$ vars } cgi " );
206207
207- $ this ->deployBinary (BUILD_TARGET_CGI );
208+ $ this ->deploySAPIBinary (BUILD_TARGET_CGI );
208209 }
209210
210211 /**
@@ -233,7 +234,11 @@ protected function buildMicro(): void
233234 ->exec ('sed -i "s|//lib|/lib|g" Makefile ' )
234235 ->exec ("make {$ concurrency } {$ vars } micro " );
235236
236- $ this ->deployBinary (BUILD_TARGET_MICRO );
237+ // deploy micro.sfx
238+ $ dst = $ this ->deploySAPIBinary (BUILD_TARGET_MICRO );
239+
240+ // patch after UPX-ed micro.sfx
241+ $ this ->processUpxedMicroSfx ($ dst );
237242 } finally {
238243 if ($ this ->phar_patched ) {
239244 SourcePatcher::unpatchMicroPhar ();
@@ -252,7 +257,7 @@ protected function buildFpm(): void
252257 ->exec ('sed -i "s|//lib|/lib|g" Makefile ' )
253258 ->exec ("make {$ concurrency } {$ vars } fpm " );
254259
255- $ this ->deployBinary (BUILD_TARGET_FPM );
260+ $ this ->deploySAPIBinary (BUILD_TARGET_FPM );
256261 }
257262
258263 /**
@@ -272,10 +277,48 @@ protected function buildEmbed(): void
272277 ->exec ('sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = / ' . basename (BUILD_MODULES_PATH ) . '|" Makefile ' )
273278 ->exec ("make {$ concurrency } INSTALL_ROOT= " . BUILD_ROOT_PATH . " {$ vars } install-sapi {$ install_modules } install-build install-headers install-programs " );
274279
280+ // process libphp.so for shared embed
281+ $ libphpSo = BUILD_LIB_PATH . '/libphp.so ' ;
282+ if (file_exists ($ libphpSo )) {
283+ // deploy libphp.so
284+ $ this ->deployBinary ($ libphpSo , $ libphpSo , false );
285+ // post actions: rename libphp.so to libphp-<release>.so if -release is set in LDFLAGS
286+ $ this ->processLibphpSoFile ($ libphpSo );
287+ }
288+
289+ // process libphp.a for static embed
290+ if (getenv ('SPC_CMD_VAR_PHP_EMBED_TYPE ' ) === 'static ' ) {
291+ $ AR = getenv ('AR ' ) ?: 'ar ' ;
292+ f_passthru ("{$ AR } -t " . BUILD_LIB_PATH . "/libphp.a | grep ' \\.a$' | xargs -n1 {$ AR } d " . BUILD_LIB_PATH . '/libphp.a ' );
293+ // export dynamic symbols
294+ SystemUtil::exportDynamicSymbols (BUILD_LIB_PATH . '/libphp.a ' );
295+ }
296+
297+ // patch embed php scripts
298+ $ this ->patchPhpScripts ();
299+ }
300+
301+ /**
302+ * Return extra variables for php make command.
303+ */
304+ private function getMakeExtraVars (): array
305+ {
306+ $ config = (new SPCConfigUtil ($ this , ['libs_only_deps ' => true , 'absolute_libs ' => true ]))->config ($ this ->ext_list , $ this ->lib_list , $ this ->getOption ('with-suggested-exts ' ), $ this ->getOption ('with-suggested-libs ' ));
307+ $ static = SPCTarget::isStatic () ? '-all-static ' : '' ;
308+ $ lib = BUILD_LIB_PATH ;
309+ return array_filter ([
310+ 'EXTRA_CFLAGS ' => getenv ('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS ' ),
311+ 'EXTRA_LIBS ' => $ config ['libs ' ],
312+ 'EXTRA_LDFLAGS ' => getenv ('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS ' ),
313+ 'EXTRA_LDFLAGS_PROGRAM ' => "-L {$ lib } {$ static } -pie " ,
314+ ]);
315+ }
316+
317+ private function processLibphpSoFile (string $ libphpSo ): void
318+ {
275319 $ ldflags = getenv ('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS ' ) ?: '' ;
276320 $ libDir = BUILD_LIB_PATH ;
277321 $ modulesDir = BUILD_MODULES_PATH ;
278- $ libphpSo = "{$ libDir }/libphp.so " ;
279322 $ realLibName = 'libphp.so ' ;
280323 $ cwd = getcwd ();
281324
@@ -337,33 +380,29 @@ protected function buildEmbed(): void
337380 }
338381 }
339382 }
340-
341- if (getenv ('SPC_CMD_VAR_PHP_EMBED_TYPE ' ) === 'static ' ) {
342- $ AR = getenv ('AR ' ) ?: 'ar ' ;
343- f_passthru ("{$ AR } -t " . BUILD_LIB_PATH . "/libphp.a | grep ' \\.a$' | xargs -n1 {$ AR } d " . BUILD_LIB_PATH . '/libphp.a ' );
344- // export dynamic symbols
345- SystemUtil::exportDynamicSymbols (BUILD_LIB_PATH . '/libphp.a ' );
346- }
347-
348- if (!$ this ->getOption ('no-strip ' , false ) && file_exists (BUILD_LIB_PATH . '/ ' . $ realLibName )) {
349- shell ()->cd (BUILD_LIB_PATH )->exec ("strip --strip-unneeded {$ realLibName }" );
350- }
351- $ this ->patchPhpScripts ();
352383 }
353384
354385 /**
355- * Return extra variables for php make command.
386+ * Patch micro.sfx after UPX compression.
387+ * micro needs special section handling in LinuxBuilder.
388+ * The micro.sfx does not support UPX directly, but we can remove UPX
389+ * info segment to adapt.
390+ * This will also make micro.sfx with upx-packed more like a malware fore antivirus
356391 */
357- private function getMakeExtraVars ( ): array
392+ private function processUpxedMicroSfx ( string $ dst ): void
358393 {
359- $ config = (new SPCConfigUtil ($ this , ['libs_only_deps ' => true , 'absolute_libs ' => true ]))->config ($ this ->ext_list , $ this ->lib_list , $ this ->getOption ('with-suggested-exts ' ), $ this ->getOption ('with-suggested-libs ' ));
360- $ static = SPCTarget::isStatic () ? '-all-static ' : '' ;
361- $ lib = BUILD_LIB_PATH ;
362- return array_filter ([
363- 'EXTRA_CFLAGS ' => getenv ('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS ' ),
364- 'EXTRA_LIBS ' => $ config ['libs ' ],
365- 'EXTRA_LDFLAGS ' => getenv ('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS ' ),
366- 'EXTRA_LDFLAGS_PROGRAM ' => "-L {$ lib } {$ static } -pie " ,
367- ]);
394+ if ($ this ->getOption ('with-upx-pack ' ) && version_compare ($ this ->getMicroVersion (), '0.2.0 ' ) >= 0 ) {
395+ // strip first
396+ // cut binary with readelf
397+ [$ ret , $ out ] = shell ()->execWithResult ("readelf -l {$ dst } | awk '/LOAD|GNU_STACK/ {getline; print \$1, \$2, \$3, \$4, \$6, \$7}' " );
398+ $ out [1 ] = explode (' ' , $ out [1 ]);
399+ $ offset = $ out [1 ][0 ];
400+ if ($ ret !== 0 || !str_starts_with ($ offset , '0x ' )) {
401+ throw new PatchException ('phpmicro UPX patcher ' , 'Cannot find offset in readelf output ' );
402+ }
403+ $ offset = hexdec ($ offset );
404+ // remove upx extra wastes
405+ file_put_contents ($ dst , substr (file_get_contents ($ dst ), 0 , $ offset ));
406+ }
368407 }
369408}
0 commit comments