Hallo, Wir verwenden hier eine GNU SPARC-Toolchain und haben folgendes Problem, bekommen es aber nicht gelöst. Wir verwenden in einem Bootloader das vom Linkerscript zur Verfügung gestellte Label "_etext", welches das Ende des Textsegmentes angibt. Weiter verwendeten wir an einer anderen Stelle im Buildprozess den Output von 'sparc-elf-size' um auch an an die Endadresse von Textsegment zu kommen. Also z.B. Output von 'sparc-elf-size':
1 | sparc-elf-size copymon |
2 | text data bss dec hex filename |
3 | 5182 0 0 5182 143e copymon |
Das vom Linker (Script) zur Verfügung gestellte Label '_etext' hatte dann auch die Adresse 0x143e. Alles funktionierte wunderbar in der Vergangenheit. Seit kurzem haben wir einen Update der Toolchain gemacht. Das führte jetzt dazu, dass das Label '_etext' nicht mehr auf der Adresse 0x143e liegt, sondern früher. Die Frage die sich stellt, warum gibt 'sparc-elf-size' eine Länge von 0x143e vom Textsegment aus? Ich finde in dem Mapfile auch keine Bezug dazu. Wo müßte ich im Linkerscript ein 'PROVIDE (_MEIN_etext = .);' einbauen, dass dann auf die von 'sparc-elf-size' angegebene size paßt. Leider richtet sich unser Buildprozess nach der von 'sparc-elf-size' angegebenen Größe und im Programm verwenden wir 'etext', was jetzt nicht mehr zusammenpaßt. Wenn es nicht anders geht, müßten wir den Output von objdump nutzen. Aber verstehen (oder so lösen) würde ich das trotzdem gerne. Es folgen jetzt der Mapfile, der Output von objdump und das Linkerscript. Für einen Hinweis wäre ich sehr dankbar. Ach ja, ich abe festgestellt, dass in '.rodata' die Stringkonstanten des Programms liegen. Aber wenn wir an das Ende von '.rodata' einen PROVIDE einbauen, kommen wir wohl nicht auf die richtige Adresse. Gruß 900ss Mapfile Hier ist der Auszug des Mapfiles:
1 | .text 0x10000000 0x12bc |
2 | *(.text .stub .text.* .gnu.linkonce.t.*) |
3 | .text 0x10000000 0x230 leoninit.o |
4 | 0x10000168 _romwindow_overflow |
5 | 0x10000000 leoninitCopymon |
6 | 0x100001cc _romwindow_underflow |
7 | .text 0x10000230 0x2f4 copymon.o |
8 | 0x10000230 copyMon |
9 | .text 0x10000524 0x1c8 uartLib.o |
10 | 0x10000574 transmitByteNoWait |
11 | 0x10000540 uartDisable |
12 | 0x1000058c transmitByte |
13 | 0x10000654 receiveByteNoWait |
14 | 0x10000614 uartRxReady |
15 | 0x10000690 uartInit |
16 | 0x10000680 keyHit |
17 | 0x100005b4 transmitString |
18 | 0x1000055c uartTxReady |
19 | 0x10000524 uartEnable |
20 | 0x10000628 receiveByte |
21 | .text 0x100006ec 0x4c8 strtools.o |
22 | 0x100007dc splitWordFromString |
23 | 0x10000908 hexStringToBin |
24 | 0x10000764 stringMatch |
25 | 0x10000a9c decToUlong |
26 | 0x100009f0 hexToUlong |
27 | 0x10000b40 strToUlong |
28 | 0x100006ec stringCopy |
29 | 0x1000072c stringLength |
30 | .text 0x10000bb4 0x414 memtools.o |
31 | 0x10000e4c dumpMemByte |
32 | 0x10000bb4 dumpMemLong |
33 | 0x10000f9c myMemcopy |
34 | 0x10000f70 copyMem |
35 | 0x10000cf4 dumpMemShort |
36 | .text 0x10000fc8 0x2dc numout.o |
37 | 0x100011cc writeByteHex |
38 | 0x10000fc8 writeUlongHex |
39 | 0x100010ac writeUlongDec |
40 | 0x10001224 writeByteDec |
41 | 0x1000106c writeUlongASCII |
42 | 0x10001184 writeUshortASCII |
43 | 0x10001128 writeUshortHex |
44 | 0x100011fc writeByteASCII |
45 | .text 0x100012a4 0x18 go.o |
46 | 0x100012a4 go |
47 | *(.gnu.warning) |
48 | |
49 | .fini 0x100012bc 0x0 |
50 | 0x100012bc _fini = . |
51 | *(.fini$00) |
52 | *(.fini$0[1-9]) |
53 | *(.fini$[1-8][0-9]) |
54 | *(.fini$9[0-8]) |
55 | *(.fini) |
56 | *(.fini$99) |
57 | 0x100012bc PROVIDE (__etext, .) |
58 | 0x100012bc PROVIDE (_etext, .) |
59 | 0x100012bc PROVIDE (__etext_unrelocated, .) |
60 | 0x100012bc PROVIDE (_etext_unrelocated, .) |
61 | 0x100012bc PROVIDE (etext_unrelocated, .) |
62 | |
63 | .rodata 0x100012c0 0x182 |
64 | *(.rodata .rodata.* .gnu.linkonce.r.*) |
65 | .rodata.str1.8 |
66 | 0x100012c0 0x162 copymon.o |
67 | 0x168 (size before relaxing) |
68 | *fill* 0x10001422 0x6 00 |
69 | .rodata.str1.8 |
70 | 0x10001428 0x1a numout.o |
71 | 0x20 (size before relaxing) |
72 | |
73 | .rodata1 |
74 | *(.rodata1) |
75 | |
76 | .eh_frame_hdr |
77 | *(.eh_frame_hdr) |
78 | 0x10001442 . = . |
79 | 0x10001448 . = ALIGN (0x8) |
80 | 0x10001448 PROVIDE (__preinit_array_start, .) |
81 | |
82 | .preinit_array |
83 | *(.preinit_array) |
84 | 0x10001448 PROVIDE (__preinit_array_end, .) |
85 | 0x10001448 PROVIDE (__init_array_start, .) |
86 | |
87 | .init_array |
88 | *(.init_array) |
89 | 0x10001448 PROVIDE (__init_array_end, .) |
90 | 0x10001448 PROVIDE (__fini_array_start, .) |
91 | |
92 | .fini_array |
93 | *(.fini_array) |
94 | 0x10001448 PROVIDE (__fini_array_end, .) |
95 | |
96 | .data 0x10001448 0x0 |
97 | *(.data .data.* .gnu.linkonce.d.*) |
sparc-elf-objdump Hier ist der Output von 'sparc-elf-objdump' dazu.
1 | sparc-elf-objdump -x copymon |
2 | |
3 | copymon: file format elf32-sparc |
4 | copymon |
5 | architecture: sparc, flags 0x00000012: |
6 | EXEC_P, HAS_SYMS |
7 | start address 0x10000000 |
8 | |
9 | Program Header: |
10 | LOAD off 0x00000078 vaddr 0x10000000 paddr 0x10000000 align 2**3 |
11 | filesz 0x00001448 memsz 0x00001448 flags rwx |
12 | |
13 | Sections: |
14 | Idx Name Size VMA LMA File off Algn |
15 | 0 .text 000012bc 10000000 10000000 00000078 2**3 |
16 | CONTENTS, ALLOC, LOAD, CODE |
17 | 1 .init 00000000 00010074 00010074 000014c0 2**0 |
18 | CONTENTS |
19 | 2 .fini 00000000 100012bc 100012bc 000014c0 2**0 |
20 | CONTENTS |
21 | 3 .rodata 00000182 100012c0 100012c0 00001338 2**3 |
22 | CONTENTS, ALLOC, LOAD, READONLY, DATA |
23 | 4 .data 00000000 10001448 10001448 000014c0 2**0 |
24 | CONTENTS, ALLOC, LOAD, DATA |
25 | 5 .edata 00000000 10001448 10001448 000014c0 2**0 |
26 | CONTENTS |
27 | 6 .bss 00000000 10001448 10001448 000014c0 2**0 |
28 | ALLOC |
29 | 7 .comment 00000168 00000000 00000000 000014c0 2**0 |
30 | CONTENTS, READONLY |
31 | 8 .debug_aranges 000000e0 00000000 00000000 00001628 2**3 |
32 | CONTENTS, READONLY, DEBUGGING |
33 | 9 .debug_pubnames 0000029f 00000000 00000000 00001708 2**0 |
34 | CONTENTS, READONLY, DEBUGGING |
35 | 10 .debug_info 00000c7b 00000000 00000000 000019a7 2**0 |
36 | CONTENTS, READONLY, DEBUGGING |
37 | 11 .debug_abbrev 000004d4 00000000 00000000 00002622 2**0 |
38 | CONTENTS, READONLY, DEBUGGING |
39 | 12 .debug_line 00000423 00000000 00000000 00002af6 2**0 |
40 | CONTENTS, READONLY, DEBUGGING |
41 | 13 .debug_frame 00000328 00000000 00000000 00002f1c 2**2 |
42 | CONTENTS, READONLY, DEBUGGING |
43 | 14 .debug_str 0000047e 00000000 00000000 00003244 2**0 |
44 | CONTENTS, READONLY, DEBUGGING |
45 | SYMBOL TABLE: |
46 | 10000000 l d .text 00000000 .text |
47 | 00010074 l d .init 00000000 .init |
48 | 100012bc l d .fini 00000000 .fini |
49 | 100012c0 l d .rodata 00000000 .rodata |
50 | 10001448 l d .data 00000000 .data |
51 | 10001448 l d .edata 00000000 .edata |
52 | 10001448 l d .bss 00000000 .bss |
53 | 00000000 l d .comment 00000000 .comment |
54 | 00000000 l d .debug_aranges 00000000 .debug_aranges |
55 | 00000000 l d .debug_pubnames 00000000 .debug_pubnames |
56 | 00000000 l d .debug_info 00000000 .debug_info |
57 | 00000000 l d .debug_abbrev 00000000 .debug_abbrev |
58 | 00000000 l d .debug_line 00000000 .debug_line |
59 | 00000000 l d .debug_frame 00000000 .debug_frame |
60 | 00000000 l d .debug_str 00000000 .debug_str |
Linkerscript Und hier ist der Auszug vom Linkerscript:
1 | SECTIONS |
2 | { |
3 | /* Read-only sections, merged into text segment: */ |
4 | PROVIDE (__executable_start = 0x10000); . = 0x10000 + SIZEOF_HEADERS; |
5 | .interp : { *(.interp) } |
6 | .hash : { *(.hash) } |
7 | .dynsym : { *(.dynsym) } |
8 | .dynstr : { *(.dynstr) } |
9 | .gnu.version : { *(.gnu.version) } |
10 | .gnu.version_d : { *(.gnu.version_d) } |
11 | .gnu.version_r : { *(.gnu.version_r) } |
12 | .rel.dyn : |
13 | { |
14 | *(.rel.init) |
15 | *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) |
16 | *(.rel.fini) |
17 | *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) |
18 | *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) |
19 | *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) |
20 | *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) |
21 | *(.rel.ctors) |
22 | *(.rel.dtors) |
23 | *(.rel.got) |
24 | *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) |
25 | } |
26 | .rela.dyn : |
27 | { |
28 | *(.rela.init) |
29 | *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) |
30 | *(.rela.fini) |
31 | *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) |
32 | *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) |
33 | *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) |
34 | *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) |
35 | *(.rela.ctors) |
36 | *(.rela.dtors) |
37 | *(.rela.got) |
38 | *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) |
39 | } |
40 | .rel.plt : { *(.rel.plt) } |
41 | .rela.plt : { *(.rela.plt) } |
42 | .init : |
43 | { |
44 | _init = .; |
45 | KEEP (*(.init$00)); |
46 | KEEP (*(.init$0[1-9])); |
47 | KEEP (*(.init$[1-8][0-9])); |
48 | KEEP (*(.init$9[0-8])); |
49 | KEEP (*(.init)) |
50 | KEEP (*(.init$99)); |
51 | } =0 |
52 | .plt : { *(.plt) } |
53 | .text : |
54 | { |
55 | *(.text .stub .text.* .gnu.linkonce.t.*) |
56 | /* .gnu.warning sections are handled specially by elf32.em. */ |
57 | *(.gnu.warning) |
58 | } =0 |
59 | .fini : |
60 | { |
61 | _fini = .; |
62 | KEEP (*(.fini$00)); |
63 | KEEP (*(.fini$0[1-9])); |
64 | KEEP (*(.fini$[1-8][0-9])); |
65 | KEEP (*(.fini$9[0-8])); |
66 | KEEP (*(.fini)) |
67 | KEEP (*(.fini$99)); |
68 | PROVIDE (__etext = .); |
69 | PROVIDE (_etext = .); |
70 | } =0 |
71 | PROVIDE (__etext_unrelocated = .); |
72 | PROVIDE (_etext_unrelocated = .); |
73 | PROVIDE (etext_unrelocated = .); |
74 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } |
75 | .rodata1 : { *(.rodata1) } |
76 | .eh_frame_hdr : { *(.eh_frame_hdr) } |
77 | /* Adjust the address for the data segment. We want to adjust up to |
78 | the same address within the page on the next page up. */ |
79 | . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x2000); |
80 | /* Ensure the __preinit_array_start label is properly aligned. We |
81 | could instead move the label definition inside the section, but |
82 | the linker would then create the section even if it turns out to |
83 | be empty, which isn't pretty. */ |
84 | . = ALIGN(8); |
85 | PROVIDE (__preinit_array_start = .); |
86 | .preinit_array : { *(.preinit_array) } |
87 | PROVIDE (__preinit_array_end = .); |
88 | PROVIDE (__init_array_start = .); |
89 | .init_array : { *(.init_array) } |
90 | PROVIDE (__init_array_end = .); |
91 | PROVIDE (__fini_array_start = .); |
92 | .fini_array : { *(.fini_array) } |
93 | PROVIDE (__fini_array_end = .); |
94 | .data : |
95 | { |
96 | *(.data .data.* .gnu.linkonce.d.*) |
97 | SORT(CONSTRUCTORS) |
98 | } |
99 | .data1 : { *(.data1) } |
100 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } |
101 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } |
102 | .eh_frame : { KEEP (*(.eh_frame)) } |
103 | .gcc_except_table : { *(.gcc_except_table) } |
104 | .dynamic : { *(.dynamic) } |
105 | .ctors : |
106 | { |
107 | /* gcc uses crtbegin.o to find the start of |
108 | the constructors, so we make sure it is |
109 | first. Because this is a wildcard, it |
110 | doesn't matter if the user does not |
111 | actually link against crtbegin.o; the |
112 | linker won't look for a file to match a |
113 | wildcard. The wildcard also means that it |
114 | doesn't matter which directory crtbegin.o |
115 | is in. */ |
116 | KEEP (*crtbegin*.o(.ctors)) |
117 | /* We don't want to include the .ctor section from |
118 | from the crtend.o file until after the sorted ctors. |
119 | The .ctor section from the crtend file contains the |
120 | end of ctors marker and it must be last */ |
121 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) |
122 | KEEP (*(SORT(.ctors.*))) |
123 | KEEP (*(.ctors)) |
124 | } |
125 | .dtors : |
126 | { |
127 | KEEP (*crtbegin*.o(.dtors)) |
128 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) |
129 | KEEP (*(SORT(.dtors.*))) |
130 | KEEP (*(.dtors)) |
131 | } |
132 | .jcr : { KEEP (*(.jcr)) } |
133 | .got : { *(.got.plt) *(.got) } |
134 | .edata : { PROVIDE (_edata = .); } |
135 | __bss_start = .; |
136 | .bss : |
137 | { |
138 | *(.dynbss) |
139 | *(.bss .bss.* .gnu.linkonce.b.*) |
140 | *(COMMON) |
141 | /* Align here to ensure that the .bss section occupies space up to |
142 | _end. Align after .bss to ensure correct alignment even if the |
143 | .bss section disappears because there are no input sections. */ |
144 | . = ALIGN(8); |
145 | } |
146 | . = ALIGN(8); |
147 | _end = .; |
148 | PROVIDE (end = .); |
149 | . = DATA_SEGMENT_END (.); |
150 | /* Stabs debugging sections. */ |
151 | .stab 0 : { *(.stab) } |
152 | .stabstr 0 : { *(.stabstr) } |
153 | .stab.excl 0 : { *(.stab.excl) } |
154 | .stab.exclstr 0 : { *(.stab.exclstr) } |
155 | .stab.index 0 : { *(.stab.index) } |
156 | .stab.indexstr 0 : { *(.stab.indexstr) } |
157 | .comment 0 : { *(.comment) } |
158 | /* DWARF debug sections. |
159 | Symbols in the DWARF debugging sections are relative to the beginning |
160 | of the section so we begin them at 0. */ |
161 | /* DWARF 1 */ |
162 | .debug 0 : { *(.debug) } |
163 | .line 0 : { *(.line) } |
164 | /* GNU DWARF 1 extensions */ |
165 | .debug_srcinfo 0 : { *(.debug_srcinfo) } |
166 | .debug_sfnames 0 : { *(.debug_sfnames) } |
167 | /* DWARF 1.1 and DWARF 2 */ |
168 | .debug_aranges 0 : { *(.debug_aranges) } |
169 | .debug_pubnames 0 : { *(.debug_pubnames) } |
170 | /* DWARF 2 */ |
171 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } |
172 | .debug_abbrev 0 : { *(.debug_abbrev) } |
173 | .debug_line 0 : { *(.debug_line) } |
174 | .debug_frame 0 : { *(.debug_frame) } |
175 | .debug_str 0 : { *(.debug_str) } |
176 | .debug_loc 0 : { *(.debug_loc) } |
177 | .debug_macinfo 0 : { *(.debug_macinfo) } |
178 | /* SGI/MIPS DWARF 2 extensions */ |
179 | .debug_weaknames 0 : { *(.debug_weaknames) } |
180 | .debug_funcnames 0 : { *(.debug_funcnames) } |
181 | .debug_typenames 0 : { *(.debug_typenames) } |
182 | .debug_varnames 0 : { *(.debug_varnames) } |
183 | PROVIDE (__ehdr = 0x10000); |
184 | PROVIDE (_ehdr = 0x10000); |
185 | /DISCARD/ : { *(.note.GNU-stack) } |
186 | } |