Cleanups Done

解决了NASM 0.99.01在生成32位/16位代码时出现的bug,该bug导致编译失败。同时发现GDB在调试含有__stdcall调用约定的代码时无法正确工作。
Clean up two old blogs, which was edited in opera (the edit box was so small). In firefox, I can review these blogs easily, and some clean up done.

NASM 0.99.01 was buggy for the 32bit/16bit codegen. When an instruction which access register and mem, it would be generated with 0x67 prefix for a 16bit segment. This blocks the elf2 bootsect, which has size limitation, extra 0x67 makes the code bloated, so the compilation breaks.
I did a quick hack, and posted the new compiled binary to the ReactOS Build Environment maintainer. Also I filed it as a bug, though the nasm64developer told me that this couldn't be reproduced in 0.99.02 CVS snapshot. O_O , after a try , yes, it's already fixed. ;) so my hacking over nasm is useless.

Though another thing interesting is spotted about GDB. GDB itself is a nice debugger. But...

c 代码
 
  1. #include "stdio.h"  
  2. void __stdcall call()  
  3. {  
  4.     printf("hello!");  
  5. }  
  6. void main()  
  7. {  
  8.     call();  
  9. }  

when you try to
gdb下调试
  1. b call  
gdb fails.

This is the reason why gdb couldn't get all symbols work in Kernel Debugging.

Remarks:
__stdcall __fastcall are calling convention in Windows, they both add @ to the mangled name, seems like gdb fail to deal with mangle name with '@'

mangle name(link time symbol):
c mangle convention: underscore prefix, so every C symbols in asm would be prefixed with an underscore.
so a typical link with ASM files would be
test.c
c 代码
 
  1. extern int myasmSymbol;    
  2. int main()    
  3. {    
  4.       return myasmSymbol;    
  5. }    
myasm.S
asm 代码
 
  1. .text  
  2. .global _myasmSymbol  
  3. _myasmSymbol: .int 0   


gcc -c myasm.S
gcc -c test.c

gcc test.o myasm.o -o test.exe






ild-libiberty-gdbserver/testsuite' make[9]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-libiberty-gdbserver' make[8]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver' /bin/sh ./../regformats/regdat.sh ../regformats/reg-arm.dat reg-arm-generated.c arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -c -o reg-arm.o -MT reg-arm.o -MMD -MP -MF .deps/reg-arm.Tpo reg-arm-generated.c /bin/sh ./../regformats/regdat.sh ../regformats/arm/arm-with-iwmmxt.dat arm-with-iwmmxt-generated.c arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -c -o arm-with-iwmmxt.o -MT arm-with-iwmmxt.o -MMD -MP -MF .deps/arm-with-iwmmxt.Tpo arm-with-iwmmxt-generated.c /bin/sh ./../regformats/regdat.sh ../regformats/arm/arm-with-vfpv2.dat arm-with-vfpv2-generated.c arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -c -o arm-with-vfpv2.o -MT arm-with-vfpv2.o -MMD -MP -MF .deps/arm-with-vfpv2.Tpo arm-with-vfpv2-generated.c /bin/sh ./../regformats/regdat.sh ../regformats/arm/arm-with-vfpv3.dat arm-with-vfpv3-generated.c arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -c -o arm-with-vfpv3.o -MT arm-with-vfpv3.o -MMD -MP -MF .deps/arm-with-vfpv3.Tpo arm-with-vfpv3-generated.c /bin/sh ./../regformats/regdat.sh ../regformats/arm/arm-with-neon.dat arm-with-neon-generated.c arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -c -o arm-with-neon.o -MT arm-with-neon.o -MMD -MP -MF .deps/arm-with-neon.Tpo arm-with-neon-generated.c rm -f gdbserver arm-sigmastar-linux-uclibcgnueabihf-g++ -Os -pipe -march=armv7-a -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wformat-nonliteral -DGDBSERVER -L/home/x/nm/nvr_2025/torchlight/staging_dir/target-arm-openwrt-linux-uclibcgnueabihf/usr/lib -L/home/x/nm/nvr_2025/torchlight/staging_dir/target-arm-openwrt-linux-uclibcgnueabihf/lib -L/home/x/nm/nvr_2025/torchlight/../sstar931/toolchain//arm-sigmastar-linux-uclibcgnueabihf/sysroot/usr/lib -static-libstdc++ -Wl,--gc-sections -Wl,--dynamic-list=./proc-service.list -o gdbserver agent.o ax.o btrace-common.o buffer.o cleanups.o common-debug.o common-exceptions.o common-regcache.o common-utils.o debug.o dll.o errors.o environ.o event-loop.o fileio.o filestuff.o format.o gdb_vecs.o hostio.o inferiors.o mem-break.o new-op.o notif.o print-utils.o ptid.o regcache.o remote-utils.o rsp-low.o server.o signals.o signals-state-save-restore.o symbol.o target.o tdesc.o tracepoint.o utils.o vec.o version.o waitstatus.o xml-utils.o reg-arm.o arm-with-iwmmxt.o arm-with-vfpv2.o arm-with-vfpv3.o arm-with-neon.o linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o linux-namespaces.o linux-arm-low.o linux-aarch32-low.o arm.o arm-linux.o arm-get-next-pcs.o hostio-errno.o thread-db.o proc-service.o posix-strerror.o xml-builtin.o \ build-gnulib-gdbserver/import/libgnu.a build-libiberty-gdbserver/libiberty.a -ldl make[8]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver' make[9]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver' make[10]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver' make[11]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make all-recursive make[12]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make[13]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make[13]: Nothing to be done for 'all-am'. make[13]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make[12]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make[11]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver/import' make[10]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver' make[9]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-gnulib-gdbserver' make[9]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-libiberty-gdbserver' make[10]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-libiberty-gdbserver/testsuite' make[10]: Nothing to be done for 'all'. make[10]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-libiberty-gdbserver/testsuite' make[9]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver/build-libiberty-gdbserver' make[8]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver' make[7]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/gdbserver' make[7]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/data-directory' make[7]: Nothing to be done for 'all'. make[7]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/data-directory' make[7]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib' make[8]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib' make[9]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make all-recursive make[10]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make[11]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make[11]: Nothing to be done for 'all-am'. make[11]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make[10]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make[9]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib/import' make[8]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib' make[7]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/build-gnulib' make[6]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' make[6]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' transformed_name=`t='s&$&&;s&^&&'; \ echo gdb | sed -e "$t"` ; \ if test "x$transformed_name" = x; then \ transformed_name=gdb ; \ else \ true ; \ fi ; \ /bin/sh ./../mkinstalldirs /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/bin ; \ /usr/bin/install -c gdb \ /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/bin/$transformed_name ; \ /bin/sh ./../mkinstalldirs /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/include/gdb ; \ /usr/bin/install -c -m 644 jit-reader.h /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/include/gdb/jit-reader.h mkdir -p -- /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/bin mkdir -p -- /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/include/gdb if test "x1" != x; \ then \ transformed_name=`t='s&$&&;s&^&&'; \ echo gcore | sed -e "$t"` ; \ if test "x$transformed_name" = x; then \ transformed_name=gcore ; \ else \ true ; \ fi ; \ /bin/sh ./../mkinstalldirs /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/bin ; \ /usr/bin/install -c gcore \ /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/ipkg-install/usr/bin/$transformed_name; \ fi make[7]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' make[8]: Entering directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/doc' (test "ln -s" = "ln -s" && \ ln -s ./all-cfg.texi gdb-cfg.texi) || \ ln ./all-cfg.texi gdb-cfg.texi || \ cp ./all-cfg.texi gdb-cfg.texi date=`sed -n -e 's/^.* BFD_VERSION_DATE \(.*\)$/\1/p' ./../../bfd/version.h`; \ sed -e "s/DATE/$date/" < ./../version.in > version.subst echo "@set GDBVN `sed q version.subst`" > ./GDBvn.new if [ -n "(GDB) " ]; then \ echo "@set VERSION_PACKAGE (GDB) " >> ./GDBvn.new; \ fi echo "@set BUGURL @uref{http://www.gnu.org/software/gdb/bugs/}" >> ./GDBvn.new if [ "@uref{http://www.gnu.org/software/gdb/bugs/}" = "@uref{http://www.gnu.org/software/gdb/bugs/}" ]; then \ echo "@set BUGURL_DEFAULT" >> ./GDBvn.new; \ fi if test -z ""; then \ echo "@set SYSTEM_READLINE" >> ./GDBvn.new; \ fi if [ -n "" ]; then \ echo "@set SYSTEM_GDBINIT " >> ./GDBvn.new; \ fi mv GDBvn.new GDBvn.texi /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/missing makeinfo --split-size=5000000 -I ./../mi -I . \ -o gdb.info ./gdb.texinfo /home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/missing: line 81: makeinfo: command not found WARNING: 'makeinfo' is missing on your system. You should only need it if you modified a '.texi' file, or any other file indirectly affecting the aspect of the manual. You might want to install the Texinfo package: <http://www.gnu.org/software/texinfo/> The spurious makeinfo call might also be the consequence of using a buggy 'make' (AIX, DU, IRIX), in which case you might want to install GNU make: <http://www.gnu.org/software/make/> Makefile:498: recipe for target 'gdb.info' failed make[8]: *** [gdb.info] Error 127 make[8]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb/doc' Makefile:2310: recipe for target 'subdir_do' failed make[7]: *** [subdir_do] Error 1 make[7]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' Makefile:2045: recipe for target 'install-only' failed make[6]: *** [install-only] Error 2 make[6]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' Makefile:2042: recipe for target 'install' failed make[5]: *** [install] Error 2 make[5]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/gdb' Makefile:8821: recipe for target 'install-gdb' failed make[4]: *** [install-gdb] Error 2 make[4]: Leaving directory '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1' Makefile:86: recipe for target '/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/.built' failed make[3]: *** [/home/x/nm/nvr_2025/torchlight/build_dir/target-arm-openwrt-linux-uclibcgnueabihf/gdb-8.0.1/.built] Error 2 make[3]: Leaving directory '/home/x/nm/nvr_2025/torchlight/package/gdb' package/Makefile:105: recipe for target 'package/gdb/compile' failed make[2]: *** [package/gdb/compile] Error 2 make[2]: Leaving directory '/home/x/nm/nvr_2025/torchlight' package/Makefile:101: recipe for target '/home/x/nm/nvr_2025/torchlight/staging_dir/target-arm-openwrt-linux-uclibcgnueabihf/stamp/.package_compile' failed make[1]: *** [/home/x/nm/nvr_2025/torchlight/staging_dir/target-arm-openwrt-linux-uclibcgnueabihf/stamp/.package_compile] Error 2 make[1]: Leaving directory '/home/x/nm/nvr_2025/torchlight' /home/x/nm/nvr_2025/torchlight/include/toplevel.mk:172: recipe for target 'world' failed make: *** [world] Error 2
09-06
chromium源码中下面的函数具体功能,详细解释一下: base::WeakPtr<content::NavigationHandle> Navigate(NavigateParams* params) { TRACE_EVENT1("navigation", "chrome::Navigate", "disposition", params->disposition); Browser* source_browser = params->browser; if (source_browser) { params->initiating_profile = source_browser->profile(); } DCHECK(params->initiating_profile); // If the created window is a partitioned popin, a valid source exists, and // the disposition is NEW_POPUP then the resulting popup should be tab-modal. // See: https://explainers-by-googlers.github.io/partitioned-popins/ params->is_tab_modal_popup |= params->window_features.is_partitioned_popin && params->source_contents && params->disposition == WindowOpenDisposition::NEW_POPUP; #if BUILDFLAG(IS_CHROMEOS) if (params->initiating_profile->IsOffTheRecord() && params->initiating_profile->GetOTRProfileID().IsCaptivePortal() && params->disposition != WindowOpenDisposition::NEW_POPUP && params->disposition != WindowOpenDisposition::CURRENT_TAB && !IncognitoModeForced(params->initiating_profile)) { // Navigation outside of the current tab or the initial popup window from a // captive portal signin window should be prevented. params->disposition = WindowOpenDisposition::CURRENT_TAB; } #endif if (params->initiating_profile->ShutdownStarted()) { // Don't navigate when the profile is shutting down. return nullptr; } // Block navigation requests when in locked fullscreen mode. We allow // navigation requests in the webapp when locked for OnTask (only relevant for // non-web browser scenarios). // TODO(b/365146870): Remove once we consolidate locked fullscreen with // OnTask. if (source_browser) { bool should_block_navigation = platform_util::IsBrowserLockedFullscreen(source_browser); #if BUILDFLAG(IS_CHROMEOS) if (source_browser->IsLockedForOnTask()) { should_block_navigation = false; } #endif // BUILDFLAG(IS_CHROMEOS) if (should_block_navigation) { return nullptr; } } // Open System Apps in their standalone window if necessary. // TODO(crbug.com/40136163): Remove this code after we integrate with intent // handling. #if BUILDFLAG(IS_CHROMEOS) const std::optional<ash::SystemWebAppType> capturing_system_app_type = ash::GetCapturingSystemAppForURL(params->initiating_profile, params->url); if (capturing_system_app_type && (!params->browser || !ash::IsBrowserForSystemWebApp(params->browser, capturing_system_app_type.value()))) { ash::SystemAppLaunchParams swa_params; swa_params.url = params->url; ash::LaunchSystemWebAppAsync(params->initiating_profile, capturing_system_app_type.value(), swa_params); // It's okay to early return here, because LaunchSystemWebAppAsync uses a // different logic to choose (and create if necessary) a browser window for // system apps. // // It's okay to skip the checks and cleanups below. The link captured system // app will either open in its own browser window, or navigate an existing // browser window exclusively used by this app. For the initiating browser, // the navigation should appear to be cancelled. return nullptr; } #endif // BUILDFLAG(IS_CHROMEOS) #if !BUILDFLAG(IS_ANDROID) // Force isolated PWAs to open in an app window. params->force_open_pwa_window = content::SiteIsolationPolicy::ShouldUrlUseApplicationIsolationLevel( params->initiating_profile, params->url); params->open_pwa_window_if_possible |= params->force_open_pwa_window; #endif if (!AdjustNavigateParamsForURL(params)) { return nullptr; } // Picture-in-picture browser windows must have a source contents in order for // the window to function correctly. If we have no source contents to work // with (e.g. if an extension popup attempts to open a PiP window), we should // cancel the navigation. The source URL must also be of a type that's // allowed to open document PiP. See `PictureInPictureWindowManager` for // details on what's allowed. if (params->disposition == WindowOpenDisposition::NEW_PICTURE_IN_PICTURE) { const GURL& url = params->source_contents ? params->source_contents->GetLastCommittedURL() : GURL(); if (!PictureInPictureWindowManager::IsSupportedForDocumentPictureInPicture( url)) { return nullptr; } } // If no source WebContents was specified, we use the selected one from the // target browser. This must happen before GetBrowserAndTabForDisposition() // has a chance to replace |params->browser| with another one, but after the // above check that relies on the original source_contents value. if (!params->source_contents && params->browser) { params->source_contents = params->browser->tab_strip_model()->GetActiveWebContents(); } WebContents* contents_to_navigate_or_insert = params->contents_to_insert.get(); if (params->switch_to_singleton_tab) { DCHECK_EQ(params->disposition, WindowOpenDisposition::SINGLETON_TAB); contents_to_navigate_or_insert = params->switch_to_singleton_tab; } #if !BUILDFLAG(IS_ANDROID) // If this is a Picture in Picture window, then notify the pip manager about // it. This enables the opener and pip window to stay connected, so that (for // example), the pip window does not outlive the opener. // // We do this before creating the browser window, so that the browser can talk // to the PictureInPictureWindowManager. Otherwise, the manager has no idea // that there's a pip window. if (params->disposition == WindowOpenDisposition::NEW_PICTURE_IN_PICTURE) { // Picture in picture windows may not be opened by other picture in // picture windows, or without an opener. if (!params->browser || params->browser->is_type_picture_in_picture()) { params->browser = nullptr; return nullptr; } PictureInPictureWindowManager::GetInstance()->EnterDocumentPictureInPicture( params->source_contents, contents_to_navigate_or_insert); } #endif // !BUILDFLAG(IS_ANDROID) // TODO(crbug.com/364657540): Revisit integration with web_application system // later if needed. int singleton_index; #if !BUILDFLAG(IS_ANDROID) std::unique_ptr<web_app::NavigationCapturingProcess> app_navigation = web_app::NavigationCapturingProcess::MaybeHandleAppNavigation(*params); std::optional<std::tuple<Browser*, int>> app_browser_tab_override; if (app_navigation) { app_browser_tab_override = app_navigation->GetInitialBrowserAndTabOverrideForNavigation(*params); } std::tie(params->browser, singleton_index) = app_browser_tab_override.has_value() ? *app_browser_tab_override : GetBrowserAndTabForDisposition(*params); #else // !BUILDFLAG(IS_ANDROID) std::tie(params->browser, singleton_index) = GetBrowserAndTabForDisposition(*params); #endif if (!params->browser) { return nullptr; } // Trying to open a background tab when in a non-tabbed app browser results in // focusing a regular browser window and opening a tab in the background // of that window. Change the disposition to NEW_FOREGROUND_TAB so that // the new tab is focused. if (source_browser && source_browser->is_type_app() && params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB && !(source_browser->app_controller() && source_browser->app_controller()->has_tab_strip())) { params->disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; } if (singleton_index != -1) { contents_to_navigate_or_insert = params->browser->tab_strip_model()->GetWebContentsAt(singleton_index); } else if (params->disposition == WindowOpenDisposition::SWITCH_TO_TAB) { // The user is trying to open a tab that no longer exists. If we open a new // tab, it could leave orphaned NTPs around, but always overwriting the // current tab could could clobber state that the user was trying to // preserve. Fallback to the behavior used for singletons: overwrite the // current tab if it's the NTP, otherwise open a new tab. params->disposition = WindowOpenDisposition::SINGLETON_TAB; ShowSingletonTabOverwritingNTP(params); return nullptr; } if (params->force_open_pwa_window) { CHECK(web_app::AppBrowserController::IsWebApp(params->browser)); } #if BUILDFLAG(IS_CHROMEOS) if (source_browser && source_browser != params->browser) { // When the newly created browser was spawned by a browser which visits // another user's desktop, it should be shown on the same desktop as the // originating one. (This is part of the desktop separation per profile). auto* window_manager = MultiUserWindowManagerHelper::GetWindowManager(); // Some unit tests have no client instantiated. if (window_manager) { aura::Window* src_window = source_browser->window()->GetNativeWindow(); aura::Window* new_window = params->browser->window()->GetNativeWindow(); const AccountId& src_account_id = window_manager->GetUserPresentingWindow(src_window); if (src_account_id != window_manager->GetUserPresentingWindow(new_window)) { // Once the window gets presented, it should be shown on the same // desktop as the desktop of the creating browser. Note that this // command will not show the window if it wasn't shown yet by the // browser creation. window_manager->ShowWindowForUser(new_window, src_account_id); } } } #endif // Navigate() must not return early after this point. if (GetSourceProfile(params) != params->browser->profile()) { // A tab is being opened from a link from a different profile, we must reset // source information that may cause state to be shared. params->opener = nullptr; params->source_contents = nullptr; params->source_site_instance = nullptr; params->referrer = content::Referrer(); } // Make sure the Browser is shown if params call for it. ScopedBrowserShower shower(params, &contents_to_navigate_or_insert); if (params->is_tab_modal_popup) { shower.set_source_contents(params->source_contents); } // Some dispositions need coercion to base types. NormalizeDisposition(params); // If a new window has been created, it needs to be shown. if (params->window_action == NavigateParams::NO_ACTION && source_browser != params->browser && params->browser->tab_strip_model()->empty()) { params->window_action = NavigateParams::SHOW_WINDOW; } // If we create a popup window from a non user-gesture, don't activate it. if (params->window_action == NavigateParams::SHOW_WINDOW && params->disposition == WindowOpenDisposition::NEW_POPUP && params->user_gesture == false) { params->window_action = NavigateParams::SHOW_WINDOW_INACTIVE; } // Determine if the navigation was user initiated. If it was, we need to // inform the target WebContents, and we may need to update the UI. bool user_initiated = params->transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR || !ui::PageTransitionIsWebTriggerable(params->transition); base::WeakPtr<content::NavigationHandle> navigation_handle; std::unique_ptr<tabs::TabModel> tab_to_insert; if (params->contents_to_insert) { tab_to_insert = std::make_unique<tabs::TabModel>(std::move(params->contents_to_insert), params->browser->tab_strip_model()); } // If no target WebContents was specified (and we didn't seek and find a // singleton), we need to construct one if we are supposed to target a new // tab. if (!contents_to_navigate_or_insert) { DCHECK(!params->url.is_empty()); if (params->disposition != WindowOpenDisposition::CURRENT_TAB) { tab_to_insert = std::make_unique<tabs::TabModel>( CreateTargetContents(*params, params->url), params->browser->tab_strip_model()); contents_to_navigate_or_insert = tab_to_insert->GetContents(); apps::SetAppIdForWebContents(params->browser->profile(), contents_to_navigate_or_insert, params->app_id); #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) captive_portal::CaptivePortalTabHelper::FromWebContents( contents_to_navigate_or_insert) ->set_window_type(params->captive_portal_window_type); #endif } else { // ... otherwise if we're loading in the current tab, the target is the // same as the source. DCHECK(params->source_contents); contents_to_navigate_or_insert = params->source_contents; } // Try to handle non-navigational URLs that popup dialogs and such, these // should not actually navigate. if (!HandleNonNavigationAboutURL(params->url)) { // Perform the actual navigation, tracking whether it came from the // renderer. navigation_handle = LoadURLInContents(contents_to_navigate_or_insert, params->url, params); } } else { // |contents_to_navigate_or_insert| was specified non-NULL, and so we assume // it has already been navigated appropriately. We need to do nothing more // other than add it to the appropriate tabstrip. } // If the user navigated from the omnibox, and the selected tab is going to // lose focus, then make sure the focus for the source tab goes away from the // omnibox. if (params->source_contents && (params->disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB || params->disposition == WindowOpenDisposition::NEW_WINDOW) && (params->tabstrip_add_types & AddTabTypes::ADD_INHERIT_OPENER)) { params->source_contents->Focus(); } if (tab_to_insert) { // Save data needed for link capturing into apps that cannot otherwise be // inferred later in the navigation. These are only needed when the // navigation happens in a different tab to the link click. apps::SetLinkCapturingSourceDisposition(tab_to_insert->GetContents(), params->disposition); } if (params->source_contents == contents_to_navigate_or_insert) { // The navigation occurred in the source tab. params->browser->UpdateUIForNavigationInTab( contents_to_navigate_or_insert, params->transition, params->window_action, user_initiated); } else if (singleton_index == -1) { if (source_browser != params->browser) { params->tabstrip_index = params->browser->tab_strip_model()->count(); } // If some non-default value is set for the index, we should tell the // TabStripModel to respect it. if (params->tabstrip_index != -1) { params->tabstrip_add_types |= AddTabTypes::ADD_FORCE_INDEX; } // Maybe notify that an open operation has been done from a gesture. // TODO(crbug.com/40719979): preferably pipe this information through the // TabStripModel instead. See bug for deeper discussion. if (params->user_gesture && source_browser == params->browser) { params->browser->window()->LinkOpeningFromGesture(params->disposition); } DCHECK(tab_to_insert); // The navigation should insert a new tab into the target Browser. params->browser->tab_strip_model()->AddTab( std::move(tab_to_insert), params->tabstrip_index, params->transition, params->tabstrip_add_types, params->group); } if (singleton_index >= 0) { // If switching browsers, make sure it is shown. if (params->disposition == WindowOpenDisposition::SWITCH_TO_TAB && params->browser != source_browser) { params->window_action = NavigateParams::SHOW_WINDOW; } if (contents_to_navigate_or_insert->IsCrashed()) { contents_to_navigate_or_insert->GetController().Reload( content::ReloadType::NORMAL, true); } else if (params->path_behavior == NavigateParams::IGNORE_AND_NAVIGATE && contents_to_navigate_or_insert->GetURL() != params->url) { navigation_handle = LoadURLInContents(contents_to_navigate_or_insert, params->url, params); } // If the singleton tab isn't already selected, select it. if (params->source_contents != contents_to_navigate_or_insert) { // Use the index before the potential close below, because it could // make the index refer to a different tab. auto gesture_type = user_initiated ? TabStripUserGestureDetails::GestureType::kOther : TabStripUserGestureDetails::GestureType::kNone; bool should_close_this_tab = false; if (params->disposition == WindowOpenDisposition::SWITCH_TO_TAB) { // Close orphaned NTP (and the like) with no history when the user // switches away from them. if (params->source_contents) { if (params->source_contents->GetController().CanGoBack() || (params->source_contents->GetLastCommittedURL().spec() != chrome::kChromeUINewTabURL && params->source_contents->GetLastCommittedURL().spec() != url::kAboutBlankURL)) { // Blur location bar before state save in ActivateTabAt() below. params->source_contents->Focus(); } else { should_close_this_tab = true; } } } params->browser->tab_strip_model()->ActivateTabAt( singleton_index, TabStripUserGestureDetails(gesture_type)); // Close tab after switch so index remains correct. if (should_close_this_tab) { params->source_contents->Close(); } } } params->navigated_or_inserted_contents = contents_to_navigate_or_insert; // At this point, the `params->navigated_or_inserted_contents` is guaranteed to // be non null, so perform tasks if the navigation has been captured by a web // app, like enqueueing launch params. #if !BUILDFLAG(IS_ANDROID) if (app_navigation) { web_app::NavigationCapturingProcess::AfterWebContentsCreation( std::move(app_navigation), *params->navigated_or_inserted_contents, navigation_handle.get()); } #endif // !BUILDFLAG(IS_ANDROID) return navigation_handle; }
08-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值