Forum: Compiler & IDEs size und objdump Unterschiede (SPARC)


von 900ss (900ss)


Lesenswert?

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
}

von yalu (Gast)


Lesenswert?

> 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.

.text hat die Größe 0x12bc (das ist auch die Adresse von _etext),
.rodata die Größe 0x182, das macht zusammen 0x143e (die von size
ausgegebene .text-Größe). Ein Provide nach .rodata liefert vermutlich
0x1442, also 4 mehr, was daran liegt, dass zwischen .text und .rodata
wegen des Section-Alignments eine Lücke von 0x4 klafft. Diese Lücke
kannst du evtl. dadurch entfernen, dass du im Linker-Skript

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

in

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

änderst. Der Punkt sollte das Alignment von .rodata verhindern, so dass
.rodata direkt an .text anschließt und damit das Ende von .rodata an
0x143e zu liegen kommt.

von 900ss (900ss)


Lesenswert?

yalu, du bist Mitarbeiter des Monats geworden ;-)

Es funktioniert mit der Änderung. Ich danke dir sehr. Hast dir echt 'n 
Bier verdient.

Leider kenne ich mich mit den Feinheiten der Linkerscripts nicht so 
besonders aus. Bei diesem Ding wußte ich nicht mehr weiter. So etwas 
ähnliches hatte ich mir gedacht. Ich muß jetzt nochmal im Linkermanual 
graben, damit ich verstehe, warum das alignment jetzt verhindert wird.

1000 Dank nochmal!

Gruß 900ss

von yalu (Gast)


Lesenswert?

> Leider kenne ich mich mit den Feinheiten der Linkerscripts nicht so
> besonders aus.

Ich auch nicht, da ich Linker-Skripte bisher zwar benutzt, aber nicht
selber geschrieben oder modifiziert habe (deswegen auch die schwammigen
Formulierungen mit "vermutlich", "evtl." und "sollte" in meinem vorigen
Beitrag :-)). Als ich aber gesehen habe, dass (.text + .rodata - Lücke)
in deinem objdump gerade den gewünschten Wert ergibt, habe ich im
ld-Manual nachgeschlagen, wie man das Alignment beeinflussen kann und
bin dabei auf diesen Abschnitt gestoßen:

  http://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address

Statt dem Punkt könnte man wahrscheinlich auch ALIGN(1) schreiben, um
das Default-Section-Alignment zu verhindern.

Eigentlich sind diese Skripte entgegen dem ersten Eindruck gar nicht so
arg magic :)

von 900ss (900ss)


Lesenswert?

yalu schrieb:
>> Leider kenne ich mich mit den Feinheiten der Linkerscripts nicht so
>> besonders aus.
>
> Ich auch nicht,

:-)

> ..., habe ich im
> ld-Manual nachgeschlagen, wie man das Alignment beeinflussen kann und
> bin dabei auf diesen Abschnitt gestoßen:

Ja, die richtige Stelle finden, das ist immer das Problem.

>
> 
http://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
>

Danke dir nochmal auch für diesen Link. Damit wird es auch klar.

> Statt dem Punkt könnte man wahrscheinlich auch ALIGN(1) schreiben, um
> das Default-Section-Alignment zu verhindern.

Ja aber es bleibt jetzt so, funktioniert ja.

> Eigentlich sind diese Skripte entgegen dem ersten Eindruck gar nicht so
> arg magic :)

Nein, man muß sich nur genügend damit beschäftigen. Aber trotzdem, 
manche Freaks gestehen doch ein, dass die Scripts "nicht so ohne" sind.
Vor allem wenn ich sehe, wieviel Zeugs da reingeschrieben wird.

Gruß
900ss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.