【Linux编程】如何使用gcc编译源代码时输出map文件?

描述

熟悉Linux环境编程的童鞋,对gcc一定不是很陌生,它可以高效地将C/C++代码编译成可执行文件。在嵌入式开发领域,gcc更是无比的强大,采用不同编译平台的gcc编译器,对应地就可以生成该平台的bin文件。由于gcc功能强大,在编译Linux内核时,gcc会是编译器的首选。

熟悉编译原理的童鞋对map文件一定很熟悉,但若是平时对底层编译不是很清晰,或者主要开发工作集中在应用层的童鞋,可能对其了解就神乎其微了。这个时候,你就需要好好阅读本文,了解下map文件了。本文要给大家分享生成map文件的方法,后续笔者会再写相关的文章介绍map文件的具体内容。

假设我们有以下的测试源码,功能很简单:

#include 

static int test_function(int arg)
{
    printf("This is a function called: %s\n", __func__);
    return arg;
}

int main(int argc, const char **argv)
{
    test_function(0);
    return 0;
}
内核

通常我们要得到可执行文件,我们会输入编译命令:

gcc -o gcc_create_map_file gcc_create_map_file.c
内核

得到输出结果,测试如下:

内核

运行结果完全符合我们的期望,编译命令完成后,在当前目录下,生成了gcc_create_map_file这个可执行文件。

但是,如果我们要编译输出可执行文件的同时,也得到可执行文件对应的map文件呢?我们可以这样输入编译命令:

gcc -o gcc_create_map_file gcc_create_map_file.c -Wl,-Map=gcc.map

 

测试输出,完全没有问题:

内核内核

​编辑

我们对比2个编译命令可以发现,其实就是在原编译命令的后面加上了 "-Wl,-Map=gcc.map";其中-Wl,是告诉gcc编译器,这个是ld的选项参数;而-Map=xxx.map就是指定map文件输出的文件名称,这个名称xxx可以随意定义,map文件的路径可以是相对路径,也可以是绝对路径。以下就是map文件的详细内容,后续会有文章对它进行详细分析,现在大家先有个感官认识。

Archive member included to satisfy reference by file (symbol)

/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
                              /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o (__libc_csu_init)

Discarded input sections

 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .note.GNU-stack
                0x0000000000000000        0x0 /tmp/cc6AliJG.o
 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
 .note.GNU-stack
                0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

Memory Configuration

Name             Origin             Length             Attributes
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

LOAD /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
LOAD /tmp/cc6AliJG.o
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so
START GROUP
LOAD /lib/x86_64-linux-gnu/libc.so.6
LOAD /usr/lib/x86_64-linux-gnu/libc_nonshared.a
LOAD /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
END GROUP
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
LOAD /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
                [!provide]                        PROVIDE (__executable_start, 0x400000)
                0x0000000000400238                . = (0x400000 + SIZEOF_HEADERS)

.interp         0x0000000000400238       0x1c
 *(.interp)
 .interp        0x0000000000400238       0x1c /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.note.ABI-tag   0x0000000000400254       0x20
 .note.ABI-tag  0x0000000000400254       0x20 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.note.gnu.build-id
                0x0000000000400274       0x24
 *(.note.gnu.build-id)
 .note.gnu.build-id
                0x0000000000400274       0x24 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.hash
 *(.hash)

.gnu.hash       0x0000000000400298       0x1c
 *(.gnu.hash)
 .gnu.hash      0x0000000000400298       0x1c /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.dynsym         0x00000000004002b8       0x60
 *(.dynsym)
 .dynsym        0x00000000004002b8       0x60 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.dynstr         0x0000000000400318       0x3f
 *(.dynstr)
 .dynstr        0x0000000000400318       0x3f /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.gnu.version    0x0000000000400358        0x8
 *(.gnu.version)
 .gnu.version   0x0000000000400358        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.gnu.version_d  0x0000000000400360        0x0
 *(.gnu.version_d)
 .gnu.version_d
                0x0000000000400360        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.gnu.version_r  0x0000000000400360       0x20
 *(.gnu.version_r)
 .gnu.version_r
                0x0000000000400360       0x20 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.rela.dyn       0x0000000000400380       0x18
 *(.rela.init)
 *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
 .rela.text     0x0000000000400380        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 *(.rela.fini)
 *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
 *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
 *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
 *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
 *(.rela.ctors)
 *(.rela.dtors)
 *(.rela.got)
 .rela.got      0x0000000000400380       0x18 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
 .rela.bss      0x0000000000400398        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
 *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
 *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
 *(.rela.ifunc)

.rela.plt       0x0000000000400398       0x30
 *(.rela.plt)
 .rela.plt      0x0000000000400398       0x30 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                [!provide]                        PROVIDE (__rela_iplt_start, .)
 *(.rela.iplt)
 .rela.iplt     0x00000000004003c8        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                [!provide]                        PROVIDE (__rela_iplt_end, .)

.init           0x00000000004003c8       0x1a
 *(SORT(.init))
 .init          0x00000000004003c8       0x15 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
                0x00000000004003c8                _init
 .init          0x00000000004003dd        0x5 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

.plt            0x00000000004003f0       0x30
 *(.plt)
 .plt           0x00000000004003f0       0x30 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000400400                printf@@GLIBC_2.2.5
                0x0000000000400410                __libc_start_main@@GLIBC_2.2.5
 *(.iplt)
 .iplt          0x0000000000400420        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.plt.got        0x0000000000400420        0x8
 *(.plt.got)
 .plt.got       0x0000000000400420        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.plt.bnd
 *(.plt.bnd)

.text           0x0000000000400430      0x1b2
 *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 .text.unlikely
                0x0000000000400430        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .text.unlikely
                0x0000000000400430        0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
 *(.text.exit .text.exit.*)
 *(.text.startup .text.startup.*)
 *(.text.hot .text.hot.*)
 *(.text .stub .text.* .gnu.linkonce.t.*)
 .text          0x0000000000400430       0x2a /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000400430                _start
 .text          0x000000000040045a        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
 *fill*         0x000000000040045a        0x6 
 .text          0x0000000000400460       0xc6 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .text          0x0000000000400526       0x44 /tmp/cc6AliJG.o
                0x000000000040054a                main
 *fill*         0x000000000040056a        0x6 
 .text          0x0000000000400570       0x72 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
                0x0000000000400570                __libc_csu_init
                0x00000000004005e0                __libc_csu_fini
 .text          0x00000000004005e2        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
 .text          0x00000000004005e2        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
 *(.gnu.warning)

.fini           0x00000000004005e4        0x9
 *(SORT(.fini))
 .fini          0x00000000004005e4        0x4 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
                0x00000000004005e4                _fini
 .fini          0x00000000004005e8        0x5 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
                [!provide]                        PROVIDE (__etext, .)
                [!provide]                        PROVIDE (_etext, .)
                [!provide]                        PROVIDE (etext, .)

.rodata         0x00000000004005f0       0x36
 *(.rodata .rodata.* .gnu.linkonce.r.*)
 .rodata.cst4   0x00000000004005f0        0x4 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x00000000004005f0                _IO_stdin_used
 *fill*         0x00000000004005f4        0x4 
 .rodata        0x00000000004005f8       0x2e /tmp/cc6AliJG.o

.rodata1
 *(.rodata1)

.eh_frame_hdr   0x0000000000400628       0x3c
 *(.eh_frame_hdr)
 .eh_frame_hdr  0x0000000000400628       0x3c /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000400628                __GNU_EH_FRAME_HDR
 *(.eh_frame_entry .eh_frame_entry.*)

.eh_frame       0x0000000000400668      0x114
 *(.eh_frame)
 .eh_frame      0x0000000000400668       0x30 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 .eh_frame      0x0000000000400698       0x40 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 .eh_frame      0x00000000004006d8       0x40 /tmp/cc6AliJG.o
                                         0x58 (size before relaxing)
 .eh_frame      0x0000000000400718       0x60 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
                                         0x78 (size before relaxing)
 .eh_frame      0x0000000000400778        0x4 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
 *(.eh_frame.*)

.gcc_except_table
 *(.gcc_except_table .gcc_except_table.*)

.gnu_extab
 *(.gnu_extab*)

.exception_ranges
 *(.exception_ranges .exception_ranges*)
                0x0000000000600e10                . = DATA_SEGMENT_ALIGN (0x200000, 0x1000)

.eh_frame
 *(.eh_frame)
 *(.eh_frame.*)

.gnu_extab
 *(.gnu_extab)

.gcc_except_table
 *(.gcc_except_table .gcc_except_table.*)

.exception_ranges
 *(.exception_ranges .exception_ranges*)

.tdata
 *(.tdata .tdata.* .gnu.linkonce.td.*)

.tbss
 *(.tbss .tbss.* .gnu.linkonce.tb.*)
 *(.tcommon)

.preinit_array  0x0000000000600e10        0x0
                [!provide]                        PROVIDE (__preinit_array_start, .)
 *(.preinit_array)
                [!provide]                        PROVIDE (__preinit_array_end, .)

.init_array     0x0000000000600e10        0x8
                0x0000000000600e10                PROVIDE (__init_array_start, .)
 *(SORT(.init_array.*) SORT(.ctors.*))
 *(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors)
 .init_array    0x0000000000600e10        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
                0x0000000000600e18                PROVIDE (__init_array_end, .)

.fini_array     0x0000000000600e18        0x8
                [!provide]                        PROVIDE (__fini_array_start, .)
 *(SORT(.fini_array.*) SORT(.dtors.*))
 *(.fini_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .dtors)
 .fini_array    0x0000000000600e18        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
                [!provide]                        PROVIDE (__fini_array_end, .)

.ctors
 *crtbegin.o(.ctors)
 *crtbegin?.o(.ctors)
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
 *(SORT(.ctors.*))
 *(.ctors)

.dtors
 *crtbegin.o(.dtors)
 *crtbegin?.o(.dtors)
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 *(SORT(.dtors.*))
 *(.dtors)

.jcr            0x0000000000600e20        0x8
 *(.jcr)
 .jcr           0x0000000000600e20        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .jcr           0x0000000000600e20        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o

.data.rel.ro
 *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
 *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)

.dynamic        0x0000000000600e28      0x1d0
 *(.dynamic)
 .dynamic       0x0000000000600e28      0x1d0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000600e28                _DYNAMIC

.got            0x0000000000600ff8        0x8
 *(.got)
 .got           0x0000000000600ff8        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 *(.igot)
                0x0000000000601fe8                . = DATA_SEGMENT_RELRO_END (., (SIZEOF (.got.plt) >= 0x18)?0x18:0x0)

.got.plt        0x0000000000601000       0x28
 *(.got.plt)
 .got.plt       0x0000000000601000       0x28 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000601000                _GLOBAL_OFFSET_TABLE_
 *(.igot.plt)
 .igot.plt      0x0000000000601028        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o

.data           0x0000000000601028       0x10
 *(.data .data.* .gnu.linkonce.d.*)
 .data          0x0000000000601028        0x4 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
                0x0000000000601028                data_start
                0x0000000000601028                __data_start
 .data          0x000000000060102c        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
 *fill*         0x000000000060102c        0x4 
 .data          0x0000000000601030        0x8 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
                0x0000000000601030                __dso_handle
 .data          0x0000000000601038        0x0 /tmp/cc6AliJG.o
 .data          0x0000000000601038        0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
 .data          0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
 .data          0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

.tm_clone_table
                0x0000000000601038        0x0
 .tm_clone_table
                0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .tm_clone_table
                0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o

.data1
 *(.data1)
                0x0000000000601038                _edata = .
                [!provide]                        PROVIDE (edata, .)
                0x0000000000601038                . = .
                0x0000000000601038                __bss_start = .

.bss            0x0000000000601038        0x8
 *(.dynbss)
 .dynbss        0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 *(.bss .bss.* .gnu.linkonce.b.*)
 .bss           0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
 .bss           0x0000000000601038        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
 .bss           0x0000000000601038        0x1 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
 .bss           0x0000000000601039        0x0 /tmp/cc6AliJG.o
 .bss           0x0000000000601039        0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
 .bss           0x0000000000601039        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
 .bss           0x0000000000601039        0x0 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
 *(COMMON)
                0x0000000000601040                . = ALIGN ((. != 0x0)?0x8:0x1)
 *fill*         0x0000000000601039        0x7 

.lbss
 *(.dynlbss)
 *(.lbss .lbss.* .gnu.linkonce.lb.*)
 *(LARGE_COMMON)
                0x0000000000601040                . = ALIGN (0x8)
                0x0000000000601040                . = SEGMENT_START ("ldata-segment", .)

.lrodata
 *(.lrodata .lrodata.* .gnu.linkonce.lr.*)

.ldata          0x0000000000a01040        0x0
 *(.ldata .ldata.* .gnu.linkonce.l.*)
                0x0000000000a01040                . = ALIGN ((. != 0x0)?0x8:0x1)
                0x0000000000a01040                . = ALIGN (0x8)
                0x0000000000a01040                _end = .
                [!provide]                        PROVIDE (end, .)
                0x0000000000a01040                . = DATA_SEGMENT_END (.)

.stab
 *(.stab)

.stabstr
 *(.stabstr)

.stab.excl
 *(.stab.excl)

.stab.exclstr
 *(.stab.exclstr)

.stab.index
 *(.stab.index)

.stab.indexstr
 *(.stab.indexstr)

.comment        0x0000000000000000       0x35
 *(.comment)
 .comment       0x0000000000000000       0x35 /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
                                         0x36 (size before relaxing)
 .comment       0x0000000000000035       0x36 /tmp/cc6AliJG.o
 .comment       0x0000000000000035       0x36 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o

.debug
 *(.debug)

.line
 *(.line)

.debug_srcinfo
 *(.debug_srcinfo)

.debug_sfnames
 *(.debug_sfnames)

.debug_aranges
 *(.debug_aranges)

.debug_pubnames
 *(.debug_pubnames)

.debug_info
 *(.debug_info .gnu.linkonce.wi.*)

.debug_abbrev
 *(.debug_abbrev)

.debug_line
 *(.debug_line .debug_line.* .debug_line_end)

.debug_frame
 *(.debug_frame)

.debug_str
 *(.debug_str)

.debug_loc
 *(.debug_loc)

.debug_macinfo
 *(.debug_macinfo)

.debug_weaknames
 *(.debug_weaknames)

.debug_funcnames
 *(.debug_funcnames)

.debug_typenames
 *(.debug_typenames)

.debug_varnames
 *(.debug_varnames)

.debug_pubtypes
 *(.debug_pubtypes)

.debug_ranges
 *(.debug_ranges)

.debug_macro
 *(.debug_macro)

.gnu.attributes
 *(.gnu.attributes)

/DISCARD/
 *(.note.GNU-stack)
 *(.gnu_debuglink)
 *(.gnu.lto_*)
OUTPUT(gcc_create_map_file elf64-x86-64)

 

好了,本文对使用gcc生成map文件的方法就介绍到这里了,如有疑问的话,可以与博主联系哦。

​  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分