亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

Name Mangling in C++

2019-11-11 07:46:46
字體:
來源:轉載
供稿:網友
摘要:詳細介紹了C++中的Name Mangling的原理和gcc中對應的實現,通過程序代碼和nm C++filt等工具來驗證這些原理。對于詳細了解程序的鏈接過程有一定的幫助。Name Mangling概述大型程序是通過多個模塊構建而成,模塊之間的關系由makefile來描述。對于由C++語言編制的大型程序而言,也是符合這個規則。程序的構建過程一般為:各個源文件分別編譯,形成目標文件。多個目標文件通過鏈接器形成最終的可執行程序。顯然,從某種程度上說,編譯器的輸出是鏈接器的輸入,鏈接器要對編譯器的輸出做二次加工。從通信的角度看,這兩個程序需要一定的協議來規范符號的組織格式。這就是Name Mangling產生的根本原因。C++的語言特性比C豐富的多,C++支持的函數重載功能是需要Name Mangling技術的最直接的例子。對于重載的函數,不能僅依靠函數名稱來區分不同的函數,因為C++中重載函數的區分是建立在以下規則上的:函數名字不同 || 參數數量不同||某個參數的類型不同那么區分函數的時候,應該充分考慮參數數量和參數類型這兩種語義信息,這樣才能為卻分不同的函數保證充分性。當然,C++還有很多其他的地方需要Name Mangling,如namespace, class, template等等??偟膩碚f,Name Mangling就是一種規范編譯器和鏈接器之間用于通信的符號表表示方法的協議,其目的在于按照程序的語言規范,使符號具備足夠多的語義信息以保證鏈接過程準確無誤的進行。簡單的實驗Name Mangling會帶了一個很常見的負面效應,就是C語言的程序調用C++的程序時,會比較棘手。因為C語言中的Name Mangling很簡單,不如C++中這么復雜。下面的代碼用于演示這兩種不同點: 1. /*2. * simple_test.c3. * a demo to show that different name mangling technology in C++ and C4. 5. * Author: Chaos Lee6. 7. */8.  9. #include<stdio.h>10.  11. int rect_area(int x1,int x2,int y1,int y2)12. 13. {14.         return (x2-x1) * (y2-y1);15. }16.  17. int elipse_area(int a,int b)18. 19. {20.         return 3.14 * a * b;21. }22.  23. int main(int argc,char *argv[])24. 25. {26.         int x1 = 10, x2 = 20, y1 = 30, y2 = 40;27.         int a = 3,b=4;28.         int result1 = rect_area(x1,x2,y1,y2);29.         int result2 = elipse_area(a,b);30.         return 0;31. } 1. [lichao@sg01 name_mangling]$ gcc -c simple_test.c2. 3. [lichao@sg01 name_mangling]$ nm simple_test.o4. 5. 0000000000000027 T elipse_area6. 7. 0000000000000051 T main8. 9. 0000000000000000 T rect_area從上面的輸出結果上,可以看到使用gcc編譯后對應的符號表中,幾乎沒有對函數做任何修飾。接下來使用g++編譯: 1.  [lichao@sg01 name_mangling]$ nm simple_test.o2. 0000000000000028 T _Z11elipse_areaii3. 4. 0000000000000000 T _Z9rect_areaiiii5. 6.                  U __gxx_personality_v07. 0000000000000052 T main顯然,g++編譯器對符號的改編比較復雜。所以,如果一個由C語言編譯的目標文件中調用了C++中實現的函數,肯定會出錯的,因為符號不匹配。簡單對_Z9rect_areaiiii做個介紹:l C++語言中規定 :以下劃線并緊挨著大寫字母開頭或者以兩個下劃線開頭的標識符都是C++語言中保留的標示符。所以_Z9rect_areaiiii是保留的標識符,g++編譯的目標文件中的符號使用_Z開頭(C99標準)。l 接下來的部分和網絡協議很類似。9表示接下來的要表示的一個字符串對象的長度(現在知道為什么不讓用數字作為標識符的開頭了吧?)所以rect_area這九個字符就作為函數的名稱被識別出來了。l 接下來的每個小寫字母表示參數的類型,i表示int類型。小寫字母的數量表示函數的參數列表中參數的數量。l 所以,在符號中集成了用于區分不同重載函數的足夠的語義信息。如果要在C語言中調用C++中的函數該怎么做?這時候可以使用C++的關鍵字extern “C”。對應代碼如下: 1. /*2. * simple_test.c3. * a demo to show that different name mangling technology in C++ and C4. 5. * Author: Chaos Lee6. 7. */8.  9. #include<stdio.h>10.  11. #ifdef __cplusplus12. 13. extern "C" {14. 15. #endif16. int rect_area(int x1,int x2,int y1,int y2)17. 18. {19.         return (x2-x1) * (y2-y1);20. }21.  22. int elipse_area(int a,int b)23. 24. {25.         return (int)(3.14 * a * b);26. }27.  28. #ifdef __cplusplus29. 30. }31. #endif32.  33. int main(int argc,char *argv[])34. 35. {36.         int x1 = 10, x2 = 20, y1 = 30, y2 = 40;37.         int a = 3,b=4;38.         int result1 = rect_area(x1,x2,y1,y2);39.         int result2 = elipse_area(a,b);40.         return 0;41. }下面是使用gcc編譯的結果: 1. [lichao@sg01 name_mangling]$ gcc -c simple_test.c2. 3. [lichao@sg01 name_mangling]$ nm simple_test.o4. 5. 0000000000000027 T elipse_area6. 7. 0000000000000051 T main8. 9. 0000000000000000 T rect_area在使用g++編譯一次: 1. [lichao@sg01 name_mangling]$ g++ -c simple_test.c2. 3. [lichao@sg01 name_mangling]$ nm simple_test.o4. 5.                  U __gxx_personality_v06. 7. 0000000000000028 T elipse_area8. 9. 0000000000000052 T main10. 11. 0000000000000000 T rect_area可見,使用extern “C”關鍵字之后,符號按照C語言的格式來組織了。事實上,C標準庫中使用了大量的extern “C”關鍵字,因為C標準庫也是可以用C++編譯器編譯的,但是要確保編譯之后仍然保持C的接口而不是C++的接口(因為是C標準庫),所以需要使用extern “C”關鍵字。下面是一個簡單的例子: 1. /*2. * libc_test.c3. * a demo PRogram to show that how the standard C4. 5. * library are compiled when encountering a C++ compiler6. 7. */8. #include<stdio.h>9. int main(int argc,char * argv[])10. 11. {12.         puts("hello world./n");13.         return 0;14. }搜索一下puts,我們并沒有看到extern “C”.奇怪么? 1. [lichao@sg01 name_mangling]$ g++ -E libc_test.c | grep 'puts'2. 3. extern int fputs (__const char *__restrict __s, FILE *__restrict __stream);4. 5. extern int puts (__const char *__s);6. 7. extern int fputs_unlocked (__const char *__restrict __s,8. 9.  puts("hello world./n");搜索一下 extern “C”試下 1. [lichao@sg01 name_mangling]$ g++ -E libc_test.c | grep 'extern "C"'2. 3. extern "C" {4. 5. extern "C" {這是由于extern “C”可以使用{}的形式將其作用域內的函數全部聲明為C語言可調用的接口形式。標準不同編譯器使用不同的方式進行name mangling, 你可能會問為什么不將C++的 name mangling標準化,這樣就能實現各個編譯器之間的互操作了。事實上,在C++的FAQ列表上有對此問題的回答:"Compilers differ as to how objects are laid out, how multiple inheritance is implemented, how virtual function calls are handled, and so on, so if the name mangling were made the same, your programs would link against libraries provided from other compilers but then crash when run. For this reason, the ARM (Annotated C++ Reference Manual) encourages compiler writers to make their name mangling different from that of other compilers for the same platform. Incompatible libraries are then detected at link time, rather than at run time."“編譯器由于內部實現的不同而不同,內部實現包括對象在內存中的布局,繼承的實現,虛函數調用處理等等。所以如果將name mangling標準化了,不錯,你的程序確實能夠鏈接成功,但是運行肯定要崩的。恰恰是因為這個原因,ARM鼓勵為同一平臺提供的不同編譯器應該使用不同的name mangling方式。這樣在編譯的時候,不兼容的庫就會被檢測到,而不至于鏈接時雖然通過了,但是運行時崩潰了?!憋@然,這是基于“運行時崩潰比鏈接時失敗的代價更大”這個原則而考慮的。GCC的name manglingGCC采用IA 64的name mangling方案,此方案定義于Intel IA64 standard ABI.在g++的FAQ列表中有以下一段話:       "GNU C++ does not do name mangling in the same way as other C++ compilers.This means that object files compiled with one compiler cannot be used withanother”GNU C++的name mangling方案和其他C++編譯器方案不同,所以一種編譯器生成的目標文件并不能被另外一種編譯器生成的目標文件使用。以下為內置的編碼類型: 1. Builtin types encoding2. 3.   <builtin-type> ::= v  # void4.                  ::= w  # wchar_t5.                  ::= b  # bool6.                  ::= c  # char7.                  ::= a  # signed char8.                  ::= h  # unsigned char9.                  ::= s  # short10.                  ::= t  # unsigned short11.                  ::= i  # int12.                  ::= j  # unsigned int13.                  ::= l  # long14.                  ::= m  # unsigned long15.                  ::= x  # long long, __int6416.                  ::= y  # unsigned long long, __int6417.                  ::= n  # __int12818.                  ::= o  # unsigned __int12819.                  ::= f  # float20.                  ::= d  # double21.                  ::= e  # long double, __float8022.                  ::= g  # __float12823.                  ::= z  # ellipsis24.                  ::= u <source-name>    # vendor extended type操作符編碼:Operator encoding 1. <operator-name> ::= nw # new          2.                  ::= na        # new[]3.                  ::= dl        # delete       4.                  ::= da        # delete[]     5.                  ::= ps        # + (unary)6.                  ::= ng        # - (unary)    7.                  ::= ad        # & (unary)    8.                  ::= de        # * (unary)    9.                  ::= co        # ~            10.                  ::= pl        # +            11.                  ::= mi        # -  12. 13.                                   ::= ml        # *            14. 15.                  ::= dv        # /            16.                  ::= rm        # %            17.                  ::= an        # &            18.                  ::= or        # |            19.                  ::= eo        # ^            20.                  ::= aS        # =            21.                  ::= pL        # +=           22.                  ::= mI        # -=           23.                  ::= mL        # *=           24.                  ::= dV        # /=           25.                  ::= rM        # %=           26.                  ::= aN        # &=           27.                  ::= oR        # |=           28.                  ::= eO        # ^=           29.                  ::= ls        # <<           30.                  ::= rs        # >>           31.                  ::= lS        # <<=          32.                  ::= rS        # >>=          33.                  ::= eq        # ==           34.                  ::= ne        # !=           35.                  ::= lt        # <            36.                  ::= gt        # >            37.                  ::= le        # <=           38.                  ::= ge        # >=           39.                  ::= nt        # !            40.                  ::= aa        # &&           41.                  ::= oo        # ||           42.                  ::= pp        # ++           43.                  ::= mm        # --           44.                  ::= cm        # ,             45.                  ::= pm        # ->*          46.                  ::= pt        # ->           47.                  ::= cl        # ()           48.                  ::= ix        # []           49.                  ::= qu        # ?            50.                  ::= st        # sizeof (a type)51.                  ::= sz        # sizeof (an expression)52.                  ::= cv <type> # (cast)       53. 54.                  ::= v <digit> <source-name>   # vendor extended operator類型編碼: 1. <type> ::= <CV-qualifiers> <type>2. 3.          ::= P <type>   # pointer-to4.          ::= R <type>   # reference-to5.          ::= O <type>     # rvalue reference-to (C++0x)6.          ::= C <type>   # complex pair (C 2000)7.          ::= G <type>   # imaginary (C 2000)8.          ::= U <source-name> <type>     # vendor extended type qualifier下面是一段簡單的代碼: 1. /*2. * Author: Chaos Lee3. 4. * Description: A simple demo to show how the rules used to mangle functions' names work5. 6. * Date:2012/05/067. 8. */9. #include<iostream>10. #include<string>11. using namespace std;12. 13. int test_func(int & tmpInt,const char * ptr,double dou,string str,float f)14. 15. {16.         return 0;17. }18. int main(int argc,char * argv[])19. 20. {21.         char * test="test";22.         int intNum = 10;23.         double dou = 10.012;24.         string str="str";25.         float f = 1.2;26.         test_func(intNum,test,dou,str,f);27.         return 0;28. } 1. [lichao@sg01 name_mangling]$ g++ -c func.cpp2. 3. [lichao@sg01 name_mangling]$ nm func.cpp4. 5. nm: func.cpp: File format not recognized6. 7. [lichao@sg01 name_mangling]$ nm func.o8. 9. 0000000000000060 t _GLOBAL__I__Z9test_funcRiPKcdSsf10.                  U _Unwind_Resume11. 0000000000000022 t _Z41__static_initialization_and_destruction_0ii12. 13. 0000000000000000 T _Z9test_funcRiPKcdSsf14. 15.                  U _ZNSaIcEC1Ev16.                  U _ZNSaIcED1Ev17.                  U _ZNSsC1EPKcRKSaIcE18.                  U _ZNSsC1ERKSs19.                  U _ZNSsD1Ev20.                  U _ZNSt8ios_base4InitC1Ev21.                  U _ZNSt8ios_base4InitD1Ev22. 0000000000000000 b _ZSt8__ioinit23. 24.                  U __cxa_atexit25.                  U __dso_handle26.                  U __gxx_personality_v027. 0000000000000076 t __tcf_028. 29. 000000000000008e T main加粗的那行就是函數test_func經過name mangling之后的結果,其中:l Ri,表示對整型變量的引用l PKc:表示const char *指針l Ss:目前還沒有找到原因。先留著~l f:表示浮點型name demanglingC++的name mangling技術一般使得函數變得面目全非,而很多情況下我們在查看這些符號的時候并不需要看到這些函數name mangling之后的效果,而是想看看是否定義了某個函數,或者是否引用了某個函數,這對于我們調試程序是非常有幫助的。所以需要一種方法從name mangling之后的符號變換為name mangling之前的符號,這個過程稱之為name demangling.事實上有很多工具提供這些功能,最常用的就是c++file命令,c++filt命令接受一個name mangling之后的符號作為輸入并輸出demangling之后的符號。例如: 1. [lichao@sg01 name_mangling]$ c++filt _Z9test_funcRiPKcdSsf2. 3. test_func(int&, char const*, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)一般更常用的方法為: 1. [lichao@sg01 name_mangling]$ nm func.o | c++filt2. 3. 0000000000000060 t global constructors keyed to _Z9test_funcRiPKcdSsf4. 5.                  U _Unwind_Resume6. 0000000000000022 t __static_initialization_and_destruction_0(int, int)7. 8. 0000000000000000 T test_func(int&, char const*, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)9. 10.                  U std::allocator<char>::allocator()11. 12.                  U std::allocator<char>::~allocator()13. 14.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)15. 16.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)17. 18.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()19. 20.                  U std::ios_base::Init::Init()21.                  U std::ios_base::Init::~Init()22. 0000000000000000 b std::__ioinit23. 24.                  U __cxa_atexit25.                  U __dso_handle26.                  U __gxx_personality_v027. 0000000000000076 t __tcf_028. 29. 000000000000008e T main另外使用nm命令也可以demangle符號,使用選項-C即可,例如: 1. [lichao@sg01 name_mangling]$ nm -C func.o2. 3. 0000000000000060 t global constructors keyed to _Z9test_funcRiPKcdSsf4. 5.                  U _Unwind_Resume6. 0000000000000022 t __static_initialization_and_destruction_0(int, int)7. 8. 0000000000000000 T test_func(int&, char const*, double, std::string, float)9. 10.                  U std::allocator<char>::allocator()11. 12.                  U std::allocator<char>::~allocator()13. 14.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)15. 16.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)17. 18.                  U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()19. 20.                  U std::ios_base::Init::Init()21.                  U std::ios_base::Init::~Init()22. 0000000000000000 b std::__ioinit23. 24.                  U __cxa_atexit25.                  U __dso_handle26.                  U __gxx_personality_v027. 0000000000000076 t __tcf_028. 29. 000000000000008e T main又到了Last but not least important的時候了,還有一個特別重要的接口函數就是__cxa_demangle(),此函數的原型為: 1. namespace abi {2. extern "C" char* __cxa_demangle (const char* mangled_name,3. 4. char* buf,5. size_t* n,6. int* status);7. }用于將mangled_name所指向的mangled進行demangle并將結果存放在buf中,n為buf的大小。status存放函數執行的結果,返回值為0表示執行成功。下面是使用這個接口函數進行demangle的例子: 1. /*2. * Author: Chaos Lee3. 4. * Description: Employ __cxa_demangle to demangle a mangling function name.5. 6. * Date:2012/05/067. 8. *9. */10. #include<iostream>11. #include<cxxabi.h>12. using namespace std;13. 14. using namespace abi;15. 16. int main(int argc,char *argv[])17. 18. {19.         const char * mangled_string = "_Z9test_funcRiPKcdSsf";20. 21.         char buffer[100];22.         int status;23.         size_t n=100;24.         __cxa_demangle(mangled_string,buffer,&n,&status);25. 26.         cout<<buffer<<endl;27.         cout<<status<<endl;28.         return 0;29. }測試結果: 1. [lichao@sg01 name_mangling]$ g++ cxa_demangle.cpp -o cxa_demangle2. 3. [lichao@sg01 name_mangling]$ ./cxa_demangle4. 5. test_func(int&, char const*, double, std::string, float)6. 7. 0name mangling與黑客l 使用demangling可以破解動態鏈接庫中的沒有公開的APIl 編寫名稱為name mangling接口函數,打開重復符號的編譯開關,可以替換原來函數中鏈接函數的指向,從而改變程序的運行結果。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人网在线视频| 国产精品久久久久99| 欧美精品久久久久久久久| 成人有码视频在线播放| 亚洲日韩第一页| 午夜精品一区二区三区在线视频| 国产视频精品一区二区三区| 欧美大成色www永久网站婷| 色综合天天狠天天透天天伊人| 欧美日韩性生活视频| 亚洲国产欧美一区二区三区久久| 午夜精品三级视频福利| 亚洲aa在线观看| 中文字幕亚洲自拍| 久久久国产精品免费| 亚洲第一区在线| 日本在线观看天堂男亚洲| 亚洲国产精品久久久久| 色www亚洲国产张柏芝| 欧美二区在线播放| 日韩精品中文字幕视频在线| 岛国av一区二区| 亚洲欧美激情在线视频| 亚洲香蕉伊综合在人在线视看| 欧美性猛交xxxx黑人猛交| 亚洲精品永久免费| 亚洲九九九在线观看| 尤物九九久久国产精品的分类| 欧美黑人xxxx| 国产99久久精品一区二区永久免费| 亚洲第一综合天堂另类专| 日本19禁啪啪免费观看www| 一本大道香蕉久在线播放29| 亚洲男子天堂网| 欧洲亚洲女同hd| 国产精品69精品一区二区三区| 韩国视频理论视频久久| www.日韩视频| 日韩欧美成人区| 亚洲性线免费观看视频成熟| 精品国产91久久久久久| 亚洲女人天堂av| 国产亚洲精品久久久优势| 欧美日韩精品在线视频| 国产成人精品免高潮费视频| 日韩国产欧美精品一区二区三区| 亚洲天堂成人在线视频| 欧美影院成年免费版| 久久夜色撩人精品| 91黑丝在线观看| 欧美疯狂性受xxxxx另类| 亚洲免费伊人电影在线观看av| 91高清视频免费观看| 久久精品国产欧美激情| 国产亚洲精品久久久久久| 亚洲第一色在线| 亚洲国产精品高清久久久| 国产欧美日韩丝袜精品一区| 国内精品国产三级国产在线专| 久久亚洲精品一区二区| 久久99久久久久久久噜噜| 国产精品久久久久久久久久99| 欧美精品福利视频| 国产精品亚洲美女av网站| 欧美专区国产专区| 欧美最顶级丰满的aⅴ艳星| 欧美裸体xxxx极品少妇| 精品国产乱码久久久久久虫虫漫画| 亚洲欧洲国产一区| 国产精品扒开腿做爽爽爽男男| 一区二区三区在线播放欧美| 亚洲男女自偷自拍图片另类| 91九色在线视频| 欧美极品在线播放| 国产一区二区三区在线观看视频| 日本免费久久高清视频| 亚洲欧洲国产伦综合| 91av中文字幕| 亚洲影院在线看| 日韩欧美精品中文字幕| 色综合色综合网色综合| 欧美激情一区二区三区高清视频| 68精品国产免费久久久久久婷婷| 日韩乱码在线视频| 日韩视频精品在线| 68精品久久久久久欧美| 国产精品久久久久久久一区探花| 日韩免费在线视频| 亚洲人成在线一二| 国产91对白在线播放| 92国产精品久久久久首页| 国产丝袜一区二区| 中文字幕亚洲在线| 亚洲人免费视频| 91精品久久久久久久久青青| 国产一区玩具在线观看| 中文字幕不卡在线视频极品| 欧美特黄级在线| 精品日韩中文字幕| 国产欧美精品xxxx另类| 尤物九九久久国产精品的特点| 国产精品久久久精品| 按摩亚洲人久久| 欧美自拍大量在线观看| 日韩中文字幕欧美| 成人国产在线激情| 国产一区二区三区网站| 精品爽片免费看久久| 亚洲欧洲视频在线| 亚洲精品丝袜日韩| 亚洲美女中文字幕| 久久久久久久久久久av| 日韩av中文字幕在线免费观看| 亚洲社区在线观看| 国产精品免费小视频| 日韩精品免费在线视频| 国产精品video| 中文字幕视频在线免费欧美日韩综合在线看| 国产精品女主播| 日韩中文字幕在线看| 91精品国产综合久久男男| 91大神在线播放精品| 国产精品久久国产精品99gif| 日韩在线高清视频| 欧美成人免费观看| 国产成人免费av电影| 91久久精品在线| 成人黄色在线免费| 奇米影视亚洲狠狠色| 日韩中文视频免费在线观看| 国产亚洲视频在线| 亚洲成人激情视频| 91久久嫩草影院一区二区| 激情久久av一区av二区av三区| 亚洲第一免费网站| 国产啪精品视频网站| 久久久999精品视频| 国产一区二区三区久久精品| 日本精品视频在线观看| 久久精品99无色码中文字幕| 欧美在线观看一区二区三区| 亚洲国产精品99久久| 国产精品吹潮在线观看| 影音先锋日韩有码| 久久久国产精品一区| 日韩资源在线观看| 色偷偷88888欧美精品久久久| 日韩一区二区精品视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久久精品免费视频| 日韩国产高清污视频在线观看| 精品久久久久久久久中文字幕| 亚洲精品理论电影| 最近2019中文字幕大全第二页| 国产精品黄页免费高清在线观看| 欧美精品午夜视频| 国产成人高清激情视频在线观看| 色哟哟亚洲精品一区二区| 成人免费视频97| 久久精品在线视频| 在线日韩第一页| 亚洲精品国产精品久久清纯直播| 欧美精品在线网站| 亚洲欧美变态国产另类|