• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天衣有縫

            冠蓋滿京華,斯人獨(dú)憔悴~
            posts - 35, comments - 115, trackbacks - 0, articles - 0
               :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            1.本文不是教程,只是描述c語(yǔ)言(gcc環(huán)境),編譯器,連接器,加載器,at&t匯編,ia32一些相關(guān)知識(shí)和筆記,很多需要深入的地方需要大家尋找相關(guān)的資料學(xué)習(xí)。如果發(fā)現(xiàn)錯(cuò)誤,請(qǐng)留言或通知我jinglexy at yahoo dot com dot cn,這個(gè)是我的msn。打字不易,請(qǐng)轉(zhuǎn)載時(shí)保留作者:http://m.shnenglu.com/jinglexy

            2.gcc安裝的各個(gè)部分:

             

            g++

            c++編譯器,鏈接時(shí)使用c++庫(kù)

             

            gcc

            c編譯器,鏈接時(shí)使用c庫(kù)

             

            cc1

            實(shí)際的c編譯器

             

            cc1plus

            實(shí)際的c++編譯器

             

            collect2

            使用collect2產(chǎn)生特定的全局初始化代碼,后臺(tái)處理是傳遞參數(shù)給ld完成實(shí)際的鏈接工作。

             

            crt0.o

            初始化和結(jié)束代碼

             

            libgcc

            平臺(tái)相關(guān)的庫(kù)

            gcc安裝需要的文件:

            gcc-core-3.4.6.tar.gz2          gcc核心編譯器,默認(rèn)只包含c編譯器

            gcc-g++-3.4.6.tar.bz2           g++編譯器

            gcc-testsuite-3.4.6.tar.bz2     測(cè)試套件

            ./configure && make && make install

             

            3.binutils安裝的各個(gè)部分

             

            as

            gnu匯編工具

             

            gprof

            性能分析工具

             

            ld

            gnu鏈接器

             

            make

             

             

            objcopy

            目標(biāo)文件從二進(jìn)制格式翻譯或復(fù)制到另一種

             

            objdump

            顯示目標(biāo)文件的各種信息

             

            strings

            顯示文件的字符串

             

            strip

            去除符合表

             

            readelf

            分析elf并顯示信息

            鏈接器可以讀寫(xiě)各種目標(biāo)文件中的信息,通過(guò)BFDbinary file descriptor)提供的工具實(shí)現(xiàn),BFD定義了類似a.out, elf, coff等目標(biāo)文件的格式。

             

            4.gcc預(yù)處理程序

            1)define指令

            #可將傳遞的宏字符串化

            ##將兩個(gè)名字連接成一個(gè)(注意不是連接成字符串)

            例:#define  TEST(ARGTERM)        \

                    printf(“the term “ #ARGTERM “is a string\n”)

            使用__VA_ARGS__定義可變參數(shù)宏

            例:#define err(...)    fprintf(stderr, __VA_ARGS)

                err (“%s %d\n”, “error code is”, 48);

            為了消除無(wú)參數(shù)時(shí)的逗號(hào),可以用下面方法定義:

                   # define err(...)        fprintf(stderr, ##__VA_ARGS)

                   一種等同的方法是:

                   #define dprintf(fmt, arg...)    printf(fmt, ##arg)

            其他例:#define  PASTE(a, b)          a##b

            2)error warning指令

            #error “y here? bad boy!”

            3)if, elif, else, endif指令

                   支持的運(yùn)算符:加減乘除,位移,&&||!

                   示例:#if defined (CONFIG_A) || defined (CONFIG_B)

                                        ……

                         #endif

            4)gcc預(yù)定義宏

             

            __BASE_FILE__

            完整的源文件名路徑

             

            __cplusplus

            測(cè)試c++程序

             

            __DATE__

             

             

            __FILE__

            源文件名

             

            __func__

            替代__FUNCTION____FUNCTION__以被GNU不推薦使用

             

            __TIME__

             

             

            __LINE__

             

             

            __VERSION__

            gcc版本

             

             

             

             

            5)幾個(gè)簡(jiǎn)單例子:

            1

            #define   min(X,  Y)  \

                (__extension__ ({typeof (X) __x = (X), __y = (Y);  \

                (__x < __y) ? __x : __y; }))

            #define   max(X,  Y)  \

                (__extension__ ({typeof (X) __x = (X), __y = (Y);  \

                (__x > __y) ? __x : __y; }))

            這樣做的目的是消除宏對(duì)XY的改變的影響,例如:result = min(x++, --y); printf(x, y);

            補(bǔ)充:圓括號(hào)定義的符合語(yǔ)句可以生成返回值,例:

                          result = ({ int a = 5;

                                        int b;

                                        b = a + 3;

                                        });          將返回8

            2

            #define dprintfbin(buf, size)   do{  int i;            \

                    printf("%s(%d)@",                           \

                              __FUNCTION__, __LINE__);          \

                    for(i = 0; i < size - 1; i++){              \

                           if(0 == i % 16)                      \

                                 printf("\n");                  \

                           printf("0x%02x ", ((char*)buf)[i]);  \

                    }                                           \

                    printf("0x%02x\n", ((char*)buf)[i]);        \

            }while(0)

            這個(gè)比較簡(jiǎn)單,不用解釋了

             

            3

            #ifdef __cplusplus

            extern "C"{

            #endif

            int foo1(void);

            int foo2(void);

            #ifdef __cplusplus

            }

            #endif

            作用:在c++程序中使用c函數(shù)及庫(kù),c++編譯程序時(shí)將函數(shù)名粉碎成自己的方式,在沒(méi)有extern的情況下可能是_Z3_foo1_Z3_foo2將導(dǎo)致連接錯(cuò)誤,這里的extern表示在連接庫(kù)時(shí),使用foo1foo2函數(shù)名。

             

            5.gcc編譯的一些知識(shí)

            gcc  -E  hello.c  -o  hello.i             只預(yù)處理

            gcc  -S  hello.c  -o  hello.s             只編譯

            gcc  -c  -fpic  first.c  second.c

            編譯成共享庫(kù):-fpic選項(xiàng)告訴連接器使用got表定位跳轉(zhuǎn)指令,使加載器可以加載該動(dòng)態(tài)庫(kù)到任何地址(具體過(guò)程可在本文后面找到)

             

            6.gcc對(duì)c語(yǔ)言的擴(kuò)展

            void fetal_error()  __attribute__(noreturn); 聲明函數(shù):無(wú)返回值

            __attribute__((noinline)) int foo1(){……}定義函數(shù):不擴(kuò)展為內(nèi)聯(lián)函數(shù)

            int getlim()  __attribute__((pure, noinline));聲明函數(shù):不內(nèi)聯(lián),不修改全局變量

            void mspec(void)  __attribute__((section(“specials”)));聲明函數(shù):連接到特定節(jié)中

            補(bǔ)充:除非使用-O優(yōu)化級(jí)別,否則函數(shù)不會(huì)真正的內(nèi)聯(lián)

            其他屬性:

            函數(shù)

            always_inline

             

            函數(shù)

            const

            pure

            函數(shù)

            constructor

            加入到crt0調(diào)用的初始化函數(shù)表

            函數(shù)

            deprecated

            無(wú)論何時(shí)調(diào)用函數(shù),總是讓編譯器警告

            函數(shù)

            destructor

             

            函數(shù)

            section

            放到命名的section中,而不是默認(rèn)的.text

            變量

            aligned

            分配該變量?jī)?nèi)存地址時(shí)對(duì)齊屬性,例:

            int value __attribute__((aligned(32)));

            變量

            deprecated

            無(wú)論何時(shí)引用變量,總是讓編譯器警告

            變量

            packed

            使數(shù)據(jù)結(jié)構(gòu)使用最小的空間,例如:

            typedef  struct  zrecord{

                          char a;

                          int b __attribute((packed));

            }zrecord_t;

            變量b在內(nèi)存中和a沒(méi)有空隙

            變量

            section

            同上,例:

            int trigger __attribute__((section(“domx”))) = 0;

            類型

            aligned

            同上,例:

            struc blockm{

                          char j[3];

            }__attribute__((aligned(32)));

            類型

            deprecated

            同上

            類型

            packed

            同上

             

             

             

             

            gcc內(nèi)嵌函數(shù):

            void *__builtin_return_address(unsigned int level);

            void *__builtin_frame_address(unsigned int leve);

            以上兩個(gè)函數(shù)可以用于回溯函數(shù)棧,如果編譯器優(yōu)化成noframe呢,誰(shuí)愿意驗(yàn)證一下?

            gcc使用__asm__, __typeof__, __inline__替代asm, typeof, inline-std-ansi會(huì)使后者失去功能。

             

            標(biāo)識(shí)符局部化,使用__label__標(biāo)簽

            int main(……){

                   {

                                 __label__ jmp1;

                                 goto jmp1;

                   }

                   goto jmp1;                    /* 錯(cuò)誤:jmp1未定義 */

            }

             

            typeof的一些技巧:

             

            char *chptr

            a char point

             

            typeof (*chptr) ch;

            a char

             

            typeof (ch) *chptr2;

            a char point

             

            typeof(chptr) chparray[10];

            ten char pointers

             

            typeof(*chptr) charray[10];

            ten char

             

            typeof (ch) charray2[10];

            ten chars

             

            7.objdump程序

             

            -a

             

            文檔頭文件信息

             

            -d

             

            可執(zhí)行代碼的反匯編

             

            -D

             

            反匯編可執(zhí)行代碼及數(shù)據(jù)

             

            -f

             

            完整文件頭的內(nèi)容

             

            -h

             

            section

             

            -p

             

            目標(biāo)格式的文件頭內(nèi)容

            調(diào)試器呢?網(wǎng)上的gdb教程已足夠的多,不再畫(huà)蛇添足了。

             

            8.平臺(tái)IA32的一些知識(shí)

            指令碼格式:

            指令前綴(04字節(jié))

            操作碼(13字節(jié))

            可選修飾符(04字節(jié))

            可選數(shù)據(jù)元素(04字節(jié))

            指令前綴:較重要的有內(nèi)存鎖定前綴(smp系統(tǒng)中使用)

            操作碼:ia32唯一必須的部分

            修飾符:使用哪些寄存器,尋址方式,SIB字節(jié)

            數(shù)據(jù)元素:靜態(tài)數(shù)值或內(nèi)存位置

             

            ia32比較重要的技術(shù):指令預(yù)取,解碼管線,分支預(yù)測(cè),亂序執(zhí)行引擎

            (網(wǎng)絡(luò)上可以找到很多相關(guān)的文章)

             

            通用寄存器(8個(gè)32位):eax, ebx, ecx, edx, esi, edi, esp, ebp

            端寄存器(6個(gè)16位):cs, ds, ss, es, fs, gs

            指令指針(1個(gè)32位):eip

            浮點(diǎn)寄存器(8個(gè)80位):形成一個(gè)fpu堆棧

            控制寄存器(5個(gè)32位):cr0, cr1, cr2, cr3, cr4

                          較重要的是cr0:控制操作模式和處理器狀態(tài)

                                           cr3:內(nèi)存分頁(yè)表描述寄存器

            調(diào)試寄存器(8個(gè)32位):

            標(biāo)識(shí)寄存器(1個(gè)32位):狀態(tài),控制,系統(tǒng)(共使用17位):陷阱,中斷,進(jìn)位,溢出等

            說(shuō)明:mmx使用fpu堆棧作為寄存器,sse, sse2, sse3沒(méi)有寄存器,只提供相關(guān)的指令功能。

            9.gas匯編工具:asat&t風(fēng)格)語(yǔ)法說(shuō)明

            使用$標(biāo)識(shí)立即數(shù)

            再寄存器前面加上%

            源操作數(shù)在前,目標(biāo)操作數(shù)在后

            使用$獲取變量地址

            長(zhǎng)跳轉(zhuǎn)使用:ljmp $section, $offset

            一個(gè)簡(jiǎn)單的匯編語(yǔ)言程序框架:

            .section .data

                          ……

            .section .bss

                          ……

            .section .text

            .globl _start

            _start:

                   ……

             

            范例:

            #cpuid2.s View the CPUID Vendor ID string using C library calls

            .section .datatext

            output:

                .asciz "The processor Vendor ID is '%s'\n"

            .section .bss

                .lcomm buffer, 12

            .section .text

            .globl _start

            _start:

                movl $0, %eax

                cpuid

                movl $buffer, %edi

                movl %ebx, (%edi)

                movl %edx, 4(%edi)

                movl %ecx, 8(%edi)

                pushl $buffer

                pushl $output

                call printf

                addl $8, %esp

                pushl $0

            call exit

             

            偽指令說(shuō)明:

            data

            .ascii

            定義字符串,沒(méi)有\0結(jié)束標(biāo)記

            data

            .asciz

            \0結(jié)束標(biāo)記

            data

            .byte

            字節(jié)

            data

            .int

            32

            data

            .long

            32

            data

            .shot

            16

            bss

            .lcomm

            對(duì)于上面的例子是聲明12字節(jié)的緩沖區(qū),l標(biāo)識(shí)local,僅當(dāng)前匯編程序可用

            bss

            .comm

            通用內(nèi)存區(qū)域

            data/text

            .equ

            .equ  LINUX_SYS_CALL, 0x80

            movl $ LINUX_SYS_CALL, %eax

            說(shuō)明:equ不是宏而是常量,會(huì)占據(jù)數(shù)據(jù)/代碼段空間

             

            指令集說(shuō)明:

             

            movb/movw/movl

             

             

            cmov

            根據(jù)cf, of, pf, zf等標(biāo)識(shí)位判斷并mov

             

            xchg

            操作時(shí)會(huì)lock內(nèi)存,非常耗費(fèi)cpu時(shí)間

             

            bswap

            翻轉(zhuǎn)寄存器中字節(jié)序

             

            xadd

             

             

            pushx, popx

             

             

            pushad, popad

             

             

            jmp

             

             

            call

             

             

            cmp

             

             

            jz/jb/jne/jge

             

             

            loop

             

             

            addb/addw/addl

             

             

            subb/subw/subl

             

             

            dec/inc

             

             

            mulb/muw/mull

            無(wú)符號(hào)乘法

            源操作數(shù)長(zhǎng)度

            目標(biāo)操作數(shù)

            目標(biāo)位置

            8

            al

            ax

            16

            ax

            dx:ax

            32

            eax

            edx:eax

             

            imul有符合乘法

             

             

            divb/divw/divl

            無(wú)符合除法

            (被除數(shù)在eax中,除數(shù)在指令中給出)

            被除數(shù)

            被除數(shù)長(zhǎng)

            余數(shù)

            ax

            16

            al

            ah

            dx:ax

            32

            ax

            dx

            edx:eax

            64

            eax

            edx

             

            idiv有符合除法

             

             

            sal/shl/sar/shr

            移位

             

            rol/ror/rcl/rcr

            循環(huán)移位

             

            leal

            取地址:leal  output, %eax

            等同于:movl  $output, %eax

             

            rep

            rep movsb      執(zhí)行ecx

             

            lodsb/lodsw/lodsl

            stosb/stosw/stosl

            取存內(nèi)存中的數(shù)據(jù)









             

            gas程序范例(函數(shù)調(diào)用):

            文件1area.s定義函數(shù)area

            # area.s - The areacircumference function

            .section .text

            .type area, @function

            .globl area

            area:

               pushl %ebp

               movl %esp, %ebp

               subl $4, %esp

               fldpi

               filds 8(%ebp)

               fmul %st(0), %st(0)

               fmulp %st(0), %st(1)

               fstps -4(%ebp)

               movl -4(%ebp), %eax

               movl %ebp, %esp

               popl %ebp

               ret

             

            文件2functest4.s調(diào)用者

            # functest4.s - An example of using external functions

            .section .data

            precision:

               .byte 0x7f, 0x00

            .section .bss

               .lcomm result, 4

            .section .text

            .globl _start

            _start:

               nop

               finit

               fldcw precision

             

               pushl $10

               call area

               addl $4, %esp

               movl %eax, result

             

               pushl $2

               call area

               addl $4, %esp

               movl %eax, result

             

               pushl $120

               call area

               addl $4, %esp

               movl %eax, result

             

               movl $1, %eax

               movl $0, %ebx

               int $0x80

             

            10.讀連接器和加載器的一些筆記,感謝原作者colyli at gmail dot com,看了他翻譯的lnl及寫(xiě)的一個(gè)os,受益匪淺。

            如果不是很深入的研究連接器和加載器的話,了解一些原理就足夠了。舉個(gè)例子說(shuō)明吧:

              1 #include <unistd.h>

              2 #include <stdlib.h>

              3 #include <stdio.h>

              4 #include <string.h>

              5

              6 int a = 1;

              7 int main()

              8 {      

              9         printf("value: %d\n", a);

             10        

             11         return 0;

             12 }

            編譯指令:gcc -c hello.c -o hello.o                   匯編

            gcc -o hello hello.o                          編譯

            objdump -d hello.o                          反匯編目標(biāo)文件

            objdump -d hello                             反匯編可執(zhí)行文件

            比較兩端結(jié)果:

            objdump -d hello.o

            objdump -d hello

            00000000 <main>:

               0:   55         push  %ebp

               1:   89 e5       mov  %esp,%ebp

               3:   83 ec 08    sub   $0x8,%esp

               6:   83 e4 f0     and  $0xfffffff0,%esp

               9:   b8 00 00 00 00  mov    $0x0,%eax

               e:   83 c0 0f        add    $0xf,%eax

              11:   83 c0 0f        add    $0xf,%eax

              14:   c1 e8 04        shr    $0x4,%eax

              17:   c1 e0 04        shl   $0x4,%eax

              1a:   29 c4          sub   %eax,%esp

              1c:   83 ec 08        sub  $0x8,%esp

              1f:   ff 35 00 00 00 00  pushl  0x0

              25:   68 00 00 00 00   push   $0x0

              2a:   e8 fc ff ff ff call  2b <main+0x2b>

              2f:   83 c4 10        add $0x10,%esp

              32:   b8 00 00 00 00  mov  $0x0,%eax

              37:   c9            leave 

              38:   c3            ret   

            08048368 <main>:

             8048368: 55      push   %ebp

             8048369: 89 e5    mov    %esp,%ebp

             804836b: 83 ec 08  sub    $0x8,%esp

             804836e: 83 e4 f0  and    $0xfffffff0,%esp

             8048371: b8 00 00 00 00  mov  $0x0,%eax

             8048376: 83 c0 0f        add  $0xf,%eax

             8048379: 83 c0 0f       add   $0xf,%eax

             804837c: c1 e8 04       shr   $0x4,%eax

             804837f:  c1 e0 04      shl   $0x4,%eax

             8048382: 29 c4          sub  %eax,%esp

             8048384: 83 ec 08       sub   $0x8,%esp

             8048387: ff 35 94 95 04 08 pushl 0x8049594

             804838d: 68 84 84 04 08  push $0x8048484

             8048392:   e8 19 ff ff ff   call  80482b0

                                                       <printf@plt>

             8048397: 83 c4 10       add  $0x10,%esp

             804839a:  b8 00 00 00 00 mov $0x0,%eax

             804839f: c9            leave 

             80483a0: c3            ret   

             80483a1: 90           nop   

             80483a2: 90           nop   

             80483a3: 90           nop   

            簡(jiǎn)單說(shuō)明:由于程序運(yùn)行時(shí)訪問(wèn)內(nèi)存,執(zhí)行跳轉(zhuǎn)都需要確切的地址。所以匯編處理的目標(biāo)文件里面沒(méi)有包含,而是把這個(gè)工作放到連接器中:即定位地址。

            當(dāng)程序需要?jiǎng)討B(tài)鏈接到某個(gè)庫(kù)上時(shí),使用該庫(kù)的got表動(dòng)態(tài)定位跳轉(zhuǎn)即可。

            具體可以看colyli大俠的《鏈接器和加載器Beta 2》,及《從程序員角度看ELF

             

            11.連接器腳本ld—script(相關(guān)內(nèi)容來(lái)自《GLD中文手冊(cè)》)

            ld --verbose查看默認(rèn)鏈接腳本

            ld把一定量的目標(biāo)文件跟檔案文件連接起來(lái),并重定位它們的數(shù)據(jù),連接符號(hào)引用.一般在編譯一個(gè)程序時(shí),最后一步就是運(yùn)行ld

            實(shí)例1

            SECTIONS
            {
                  . = 0x10000;
                  .text : { *(.text) }
                  . = 0x8000000;
                  .data : { *(.data) }
                  .bss : { *(.bss) }
            }

                          注釋:“.”是定位計(jì)數(shù)器,設(shè)置當(dāng)前節(jié)的地址。

             

            實(shí)例2

            floating_point = 0;
                SECTIONS
                {

            . = ALIGN(4);
                  .text :
                    {
                      *(.text)
                       _etext = .;

            PROVIDE(etext = .);
                }

             

            . = ALIGN(4);
                  _bdata = (. + 3) & ~ 3;
                  .data : { *(.data) }
                }

            注釋:定義一個(gè)符合_etext,地址為.text結(jié)束的地方,注意源程序中不能在此定義該符合,否則鏈接器會(huì)提示重定義,而是應(yīng)該象下面這樣使用:

            extern char _etext;

            但是可以在源程序中使用etext符合,連接器不導(dǎo)出它到目標(biāo)文件。

             

            實(shí)例3

              SECTIONS {
                  outputa 0x10000 :
                    {
                    all.o
                    foo.o (.input1)
                    }
                  outputb :
                    {
                    foo.o (.input2)
                    foo1.o (.input1)
                    }
                  outputc :
                    {
                    *(.input1)
                    *(.input2)
                    }
              }

            這個(gè)例子是一個(gè)完整的連接腳本。它告訴連接器去讀取文件all.o中的所有節(jié),并把它們放到輸出節(jié)outputa的開(kāi)始位置處, 該輸出節(jié)是從位置0x10000處開(kāi)始的。從文件foo.o中來(lái)的所有節(jié).input1在同一個(gè)輸出節(jié)中緊密排列。 從文件foo.o中來(lái)的所有節(jié).input2全部放入到輸出節(jié)outputb中,后面跟上從foo1.o中來(lái)的節(jié).input1。來(lái)自所有文件的所有余下的.input1.input2節(jié)被寫(xiě)入到輸出節(jié)outputc中。

             

            示例4:連接器填充法則:

               SECTIONS { .text : { *(.text) } LONG(1) .data : { *(.data) } }                    錯(cuò)誤

                SECTIONS { .text : { *(.text) ; LONG(1) } .data : { *(.data) } }           正確

             

            示例5VMALMA不同的情況

                SECTIONS
                  {
                  .text 0x1000 : { *(.text) _etext = . ; }
                  .mdata 0x2000 :
                    AT ( ADDR (.text) + SIZEOF (.text) )
                    { _data = . ; *(.data); _edata = . ;  }
                  .bss 0x3000 :
                    { _bstart = . ;  *(.bss) *(COMMON) ; _bend = . ;}
                }

            程序:

                extern char _etext, _data, _edata, _bstart, _bend;
                char *src = &_etext;
                char *dst = &_data;

             

                /* ROM has data at end of text; copy it. */
                while (dst &lt; &_edata) {
                  *dst++ = *src++;
                }

             

                /* Zero bss */
                for (dst = &_bstart; dst&lt; &_bend; dst++)
                  *dst = 0;

            示例6linux-2.6.14/arch/i386/kernel $ vi vmlinux.lds.S

            linux內(nèi)核的鏈接腳本,自行分析吧,有點(diǎn)復(fù)雜哦。

            Feedback

            # re: gcc, as, ld的一些筆記(原創(chuàng))  回復(fù)  更多評(píng)論   

            2007-06-29 14:05 by V086.cn
            9743
            欧美国产成人久久精品| 免费观看久久精彩视频| 久久久久久噜噜精品免费直播| 国产精品无码久久综合| 无码日韩人妻精品久久蜜桃| 久久亚洲AV无码精品色午夜麻豆| 精品熟女少妇aⅴ免费久久| 国产精品美女久久久久av爽| 久久精品国产精品亚洲精品| 久久精品国产一区| 狠狠久久综合伊人不卡| 久久久无码精品亚洲日韩京东传媒| 久久精品视频一| 久久国产精品77777| 91久久成人免费| 亚州日韩精品专区久久久| 欧美日韩精品久久久久| 热re99久久精品国99热| 日本三级久久网| 四虎国产精品成人免费久久| 久久精品无码一区二区无码| 99久久精品费精品国产| 麻豆精品久久久久久久99蜜桃| 久久精品国产99久久久| 精品国产乱码久久久久久浪潮 | 一本一道久久综合狠狠老| 三级韩国一区久久二区综合| 国产精品99久久99久久久| 久久青青草原亚洲av无码app| 999久久久无码国产精品| 亚洲国产成人久久精品动漫| 麻豆国内精品久久久久久| 伊人久久大香线蕉亚洲五月天| 99久久国语露脸精品国产| 尹人香蕉久久99天天拍| 欧美777精品久久久久网| 精品无码久久久久国产动漫3d| 久久99国产精品二区不卡| 久久精品国产免费观看三人同眠| 99久久精品免费| 国产精品九九九久久九九|