您的位置:首页 > 其它

链接脚本使用----- 将二进制文件作为一个段

2014-03-13 20:10 302 查看
在分析Linux内核编译流程的时候,看到arch/arm/boot/compressed/piggy.gzip.S将压缩后的Linux内核(arch/arm/boot/compressed/piggy.gzip)包含进来:

[code]           [code] .section .piggydata,#alloc


.globl    input_data


t_data:


.incbin    "arch/arm/boot/compressed/piggy.gzip"


.globl    input_data_end


t_data_end:

[/code]
[/code]

 

我们是不是也可以利用这种方法将一副图片作为可执行程序的一个段,然后再程序中访问这个段来达到显示图片的目的?下面是我的做法:





仿照piggy.gzip.S实现demo.S:

[code]
[code] .section .peng


.incbin "./logo.jpg"

[/code]
[/code]

main.c

[code] #include <stdio.h>


 


extern unsigned int __peng_start;


extern unsigned int __peng_end;


 


char *p = (char *)(&__peng_start);


//我们要获取__peng_start的存放地址,作为字符串首地址,或者数组名来使用。


int main(int argc, const char *argv[])


{


int i;


unsigned int len = 0;


 


len = (unsigned int)(&__peng_end) - (unsigned int)(&__peng_start);


 


printf("len = %x\n", len);


 


printf("%p\n", &__peng_start);


printf("%p\n", &__peng_end);


 


for(i=0; i<len; i++)


{


if (i % 16 == 0)


  {


printf("\n");


}


printf("%3x ", *p++&0xff);


}


 


 


return 0;


}

[/code]

Makefile

[code] CC=gcc -Wall


 


main:main.o demo.o


$(CC) $^ -Tload.lds -o $@


 


main.o:main.c


 


demo.o:demo.S


 


 


clean:


$(RM) *.o main

[/code]

load.lds

[code] OUTPUT_FORMAT("elf32-i386", "elf32-i386",


"elf32-i386")


OUTPUT_ARCH(i386)


ENTRY(_start)


SEARCH_DIR("/usr/i486-linux-gnu/lib32"); SEARCH_DIR("/usr/local/lib32"); SEARCH_DIR("/lib32"); SEARCH_DIR("/usr/lib32"); SEARCH_DIR("/usr/i486-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");


SECTIONS


{


/* Read-only sections, merged into text segment: */


PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;


   .interp         :{ *(.interp)}


   .note.gnu.build-id :{ *(.note.gnu.build-id)}


   .hash           :{ *(.hash)}


   .gnu.hash       :{ *(.gnu.hash)}


   .dynsym         :{ *(.dynsym)}


   .dynstr         :{ *(.dynstr)}


   .gnu.version    :{ *(.gnu.version)}


   .gnu.version_d  :{ *(.gnu.version_d)}


   .gnu.version_r  :{ *(.gnu.version_r)}


.peng :


 {


. = ALIGN(4);


__peng_start = .;


*(.peng);


__peng_end = .;


. = ALIGN(4);


 }


.rel.dyn        :


{


*(.rel.init)


*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)


*(.rel.fini)


*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)


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


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


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


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


*(.rel.ctors)


*(.rel.dtors)


*(.rel.got)


*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)


*(.rel.ifunc)


}


.rel.plt        :


{


*(.rel.plt)


PROVIDE_HIDDEN (__rel_iplt_start = .);


*(.rel.iplt)


PROVIDE_HIDDEN (__rel_iplt_end = .);


}


.init           :


 {


KEEP (*(.init))


 } =0x90909090


   .plt            :{ *(.plt) *(.iplt)}


.text           :


 {


*(.text.unlikely .text.*_unlikely)


*(.text .stub .text.* .gnu.linkonce.t.*)


/* .gnu.warning sections are handled specially by elf32.em.  */


*(.gnu.warning)


 } =0x90909090


.fini           :


 {


KEEP (*(.fini))


 } =0x90909090


PROVIDE (__etext = .);


PROVIDE (_etext = .);


PROVIDE (etext = .);


   .rodata         :{ *(.rodata .rodata.* .gnu.linkonce.r.*)}


   .rodata1        :{ *(.rodata1)}


   .eh_frame_hdr :{ *(.eh_frame_hdr)}


   .eh_frame       : ONLY_IF_RO{ KEEP (*(.eh_frame))}


   .gcc_except_table   : ONLY_IF_RO{ *(.gcc_except_table .gcc_except_table.*)}


/* Adjust the address for the data segment.  We want to adjust up to


the same address within the page on the next page up.  */


. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));


/* Exception handling  */


   .eh_frame       : ONLY_IF_RW{ KEEP (*(.eh_frame))}


   .gcc_except_table   : ONLY_IF_RW{ *(.gcc_except_table .gcc_except_table.*)}


/* Thread Local Storage sections  */


   .tdata      :{ *(.tdata .tdata.* .gnu.linkonce.td.*)}


   .tbss          :{ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)}


.preinit_array     :


 {


PROVIDE_HIDDEN (__preinit_array_start = .);


KEEP (*(.preinit_array))


PROVIDE_HIDDEN (__preinit_array_end = .);


 }


.init_array     :


 {


PROVIDE_HIDDEN (__init_array_start = .);


KEEP (*(SORT(.init_array.*)))


KEEP (*(.init_array))


PROVIDE_HIDDEN (__init_array_end = .);


 }


.fini_array     :


 {


PROVIDE_HIDDEN (__fini_array_start = .);


KEEP (*(.fini_array))


KEEP (*(SORT(.fini_array.*)))


PROVIDE_HIDDEN (__fini_array_end = .);


 }


.ctors          :


 {


/* gcc uses crtbegin.o to find the start of


the constructors, so we make sure it is


first.  Because this is a wildcard, it


doesn't matter if the user does not


actually link against crtbegin.o; the


linker won't look for a file to match a


wildcard.  The wildcard also means that it


doesn't matter which directory crtbegin.o


is in.  */


KEEP (*crtbegin.o(.ctors))


KEEP (*crtbegin?.o(.ctors))


/* We don't want to include the .ctor section from


the crtend.o file until after the sorted ctors.


The .ctor section from the crtend file contains the


end of ctors marker and it must be last */


KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))


KEEP (*(SORT(.ctors.*)))


KEEP (*(.ctors))


 }


.dtors          :


 {


KEEP (*crtbegin.o(.dtors))


KEEP (*crtbegin?.o(.dtors))


KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))


KEEP (*(SORT(.dtors.*)))


KEEP (*(.dtors))


 }


   .jcr            :{ KEEP (*(.jcr))}


   .data.rel.ro :{ *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)}


   .dynamic        :{ *(.dynamic)}


   .got            :{ *(.got) *(.igot)}


. = DATA_SEGMENT_RELRO_END (12, .);


   .got.plt        :{ *(.got.plt)  *(.igot.plt)}


.data           :


 {


*(.data .data.* .gnu.linkonce.d.*)


SORT(CONSTRUCTORS)


 }


   .data1          :{ *(.data1)}


_edata = .; PROVIDE (edata = .);


__bss_start = .;


.bss            :


 {


*(.dynbss)


*(.bss .bss.* .gnu.linkonce.b.*)


*(COMMON)


/* Align here to ensure that the .bss section occupies space up to


_end.  Align after .bss to ensure correct alignment even if the


.bss section disappears because there are no input sections.


FIXME: Why do we need it? When there is no .bss section, we don't


pad the .data section.  */


. = ALIGN(. != 0 ? 32 / 8 : 1);


 }


. = ALIGN(32 / 8);


. = ALIGN(32 / 8);


_end = .; PROVIDE (end = .);


. = DATA_SEGMENT_END (.);


/* Stabs debugging sections.  */


   .stab          0 :{ *(.stab)}


   .stabstr       0 :{ *(.stabstr)}


   .stab.excl     0 :{ *(.stab.excl)}


   .stab.exclstr  0 :{ *(.stab.exclstr)}


   .stab.index    0 :{ *(.stab.index)}


   .stab.indexstr 0 :{ *(.stab.indexstr)}


   .comment       0 :{ *(.comment)}


/* DWARF debug sections.


Symbols in the DWARF debugging sections are relative to the beginning


of the section so we begin them at 0.  */


/* DWARF 1 */


   .debug          0 :{ *(.debug)}


   .line           0 :{ *(.line)}


/* GNU DWARF 1 extensions */


   .debug_srcinfo  0 :{ *(.debug_srcinfo)}


   .debug_sfnames  0 :{ *(.debug_sfnames)}


/* DWARF 1.1 and DWARF 2 */


   .debug_aranges  0 :{ *(.debug_aranges)}


   .debug_pubnames 0 :{ *(.debug_pubnames)}


/* DWARF 2 */


   .debug_info     0 :{ *(.debug_info .gnu.linkonce.wi.*)}


   .debug_abbrev   0 :{ *(.debug_abbrev)}


   .debug_line     0 :{ *(.debug_line)}


   .debug_frame    0 :{ *(.debug_frame)}


   .debug_str      0 :{ *(.debug_str)}


   .debug_loc      0 :{ *(.debug_loc)}


   .debug_macinfo  0 :{ *(.debug_macinfo)}


/* SGI/MIPS DWARF 2 extensions */


   .debug_weaknames 0 :{ *(.debug_weaknames)}


   .debug_funcnames 0 :{ *(.debug_funcnames)}


   .debug_typenames 0 :{ *(.debug_typenames)}


   .debug_varnames  0 :{ *(.debug_varnames)}


/* DWARF 3 */


   .debug_pubtypes 0 :{ *(.debug_pubtypes)}


   .debug_ranges   0 :{ *(.debug_ranges)}


   .gnu.attributes 0 :{ KEEP (*(.gnu.attributes))}


   /DISCARD/ :{ *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*)}


}

[/code]

 

下面是运行main的结果:





用winhex打开logo.jpg可以看到如下:





可以看到二者是一致的。(29626 = 0x73BA)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: