mikrocontroller.net

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


Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht 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':
sparc-elf-size copymon
   text    data     bss     dec     hex filename
   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:
.text           0x10000000     0x12bc
 *(.text .stub .text.* .gnu.linkonce.t.*)
 .text          0x10000000      0x230 leoninit.o
                0x10000168                _romwindow_overflow
                0x10000000                leoninitCopymon
                0x100001cc                _romwindow_underflow
 .text          0x10000230      0x2f4 copymon.o
                0x10000230                copyMon
 .text          0x10000524      0x1c8 uartLib.o
                0x10000574                transmitByteNoWait
                0x10000540                uartDisable
                0x1000058c                transmitByte
                0x10000654                receiveByteNoWait
                0x10000614                uartRxReady
                0x10000690                uartInit
                0x10000680                keyHit
                0x100005b4                transmitString
                0x1000055c                uartTxReady
                0x10000524                uartEnable
                0x10000628                receiveByte
 .text          0x100006ec      0x4c8 strtools.o
                0x100007dc                splitWordFromString
                0x10000908                hexStringToBin
                0x10000764                stringMatch
                0x10000a9c                decToUlong
                0x100009f0                hexToUlong
                0x10000b40                strToUlong
                0x100006ec                stringCopy
                0x1000072c                stringLength
 .text          0x10000bb4      0x414 memtools.o
                0x10000e4c                dumpMemByte
                0x10000bb4                dumpMemLong
                0x10000f9c                myMemcopy
                0x10000f70                copyMem
                0x10000cf4                dumpMemShort
 .text          0x10000fc8      0x2dc numout.o
                0x100011cc                writeByteHex
                0x10000fc8                writeUlongHex
                0x100010ac                writeUlongDec
                0x10001224                writeByteDec
                0x1000106c                writeUlongASCII
                0x10001184                writeUshortASCII
                0x10001128                writeUshortHex
                0x100011fc                writeByteASCII
 .text          0x100012a4       0x18 go.o
                0x100012a4                go
 *(.gnu.warning)

.fini           0x100012bc        0x0
                0x100012bc                _fini = .
 *(.fini$00)
 *(.fini$0[1-9])
 *(.fini$[1-8][0-9])
 *(.fini$9[0-8])
 *(.fini)
 *(.fini$99)
                0x100012bc                PROVIDE (__etext, .)
                0x100012bc                PROVIDE (_etext, .)
                0x100012bc                PROVIDE (__etext_unrelocated, .)
                0x100012bc                PROVIDE (_etext_unrelocated, .)
                0x100012bc                PROVIDE (etext_unrelocated, .)

.rodata         0x100012c0      0x182
 *(.rodata .rodata.* .gnu.linkonce.r.*)
 .rodata.str1.8
                0x100012c0      0x162 copymon.o
                                0x168 (size before relaxing)
 *fill*         0x10001422        0x6 00
 .rodata.str1.8
                0x10001428       0x1a numout.o
                                 0x20 (size before relaxing)

.rodata1
 *(.rodata1)

.eh_frame_hdr
 *(.eh_frame_hdr)
                0x10001442                . = .
                0x10001448                . = ALIGN (0x8)
                0x10001448                PROVIDE (__preinit_array_start, .)

.preinit_array
 *(.preinit_array)
                0x10001448                PROVIDE (__preinit_array_end, .)
                0x10001448                PROVIDE (__init_array_start, .)

.init_array
 *(.init_array)
                0x10001448                PROVIDE (__init_array_end, .)
                0x10001448                PROVIDE (__fini_array_start, .)

.fini_array
 *(.fini_array)
                0x10001448                PROVIDE (__fini_array_end, .)

.data           0x10001448        0x0
 *(.data .data.* .gnu.linkonce.d.*)

sparc-elf-objdump
Hier ist der Output von 'sparc-elf-objdump' dazu.
sparc-elf-objdump -x copymon

copymon:     file format elf32-sparc
copymon
architecture: sparc, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x10000000

Program Header:
    LOAD off    0x00000078 vaddr 0x10000000 paddr 0x10000000 align 2**3
         filesz 0x00001448 memsz 0x00001448 flags rwx

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000012bc  10000000  10000000  00000078  2**3
                  CONTENTS, ALLOC, LOAD, CODE
  1 .init         00000000  00010074  00010074  000014c0  2**0
                  CONTENTS
  2 .fini         00000000  100012bc  100012bc  000014c0  2**0
                  CONTENTS
  3 .rodata       00000182  100012c0  100012c0  00001338  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .data         00000000  10001448  10001448  000014c0  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  5 .edata        00000000  10001448  10001448  000014c0  2**0
                  CONTENTS
  6 .bss          00000000  10001448  10001448  000014c0  2**0
                  ALLOC
  7 .comment      00000168  00000000  00000000  000014c0  2**0
                  CONTENTS, READONLY
  8 .debug_aranges 000000e0  00000000  00000000  00001628  2**3
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_pubnames 0000029f  00000000  00000000  00001708  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_info   00000c7b  00000000  00000000  000019a7  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_abbrev 000004d4  00000000  00000000  00002622  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_line   00000423  00000000  00000000  00002af6  2**0
                  CONTENTS, READONLY, DEBUGGING
 13 .debug_frame  00000328  00000000  00000000  00002f1c  2**2
                  CONTENTS, READONLY, DEBUGGING
 14 .debug_str    0000047e  00000000  00000000  00003244  2**0
                  CONTENTS, READONLY, DEBUGGING
SYMBOL TABLE:
10000000 l    d  .text  00000000 .text
00010074 l    d  .init  00000000 .init
100012bc l    d  .fini  00000000 .fini
100012c0 l    d  .rodata        00000000 .rodata
10001448 l    d  .data  00000000 .data
10001448 l    d  .edata 00000000 .edata
10001448 l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .debug_aranges 00000000 .debug_aranges
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames
00000000 l    d  .debug_info    00000000 .debug_info
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev
00000000 l    d  .debug_line    00000000 .debug_line
00000000 l    d  .debug_frame   00000000 .debug_frame
00000000 l    d  .debug_str     00000000 .debug_str

Linkerscript
Und hier ist der Auszug vom Linkerscript:

SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = 0x10000); . = 0x10000 + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .hash           : { *(.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .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.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.*)
    }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.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.bss .rela.bss.* .rela.gnu.linkonce.b.*)
    }
  .rel.plt        : { *(.rel.plt) }
  .rela.plt       : { *(.rela.plt) }
  .init           :
  {
    _init = .;
            KEEP (*(.init$00));
            KEEP (*(.init$0[1-9]));
            KEEP (*(.init$[1-8][0-9]));
            KEEP (*(.init$9[0-8]));
    KEEP (*(.init))
    KEEP (*(.init$99));
  } =0
  .plt            : { *(.plt) }
  .text           :
  {
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
  } =0
  .fini           :
  {
    _fini = .;
            KEEP (*(.fini$00));
            KEEP (*(.fini$0[1-9]));
            KEEP (*(.fini$[1-8][0-9]));
            KEEP (*(.fini$9[0-8]));
    KEEP (*(.fini))
    KEEP (*(.fini$99));
          PROVIDE (__etext = .);
          PROVIDE (_etext = .);
  } =0
  PROVIDE (__etext_unrelocated = .);
  PROVIDE (_etext_unrelocated = .);
  PROVIDE (etext_unrelocated = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .eh_frame_hdr : { *(.eh_frame_hdr) }
  /* 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 (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x2000);
  /* Ensure the __preinit_array_start label is properly aligned.  We
     could instead move the label definition inside the section, but
     the linker would then create the section even if it turns out to
     be empty, which isn't pretty.  */
  . = ALIGN(8);
  PROVIDE (__preinit_array_start = .);
  .preinit_array     : { *(.preinit_array) }
  PROVIDE (__preinit_array_end = .);
  PROVIDE (__init_array_start = .);
  .init_array     : { *(.init_array) }
  PROVIDE (__init_array_end = .);
  PROVIDE (__fini_array_start = .);
  .fini_array     : { *(.fini_array) }
  PROVIDE (__fini_array_end = .);
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .eh_frame       : { KEEP (*(.eh_frame)) }
  .gcc_except_table   : { *(.gcc_except_table) }
  .dynamic        : { *(.dynamic) }
  .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))
    /* We don't want to include the .ctor section from
       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 ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin*.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .got            : { *(.got.plt) *(.got) }
  .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.  */
   . = ALIGN(8);
  }
  . = ALIGN(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) }
  PROVIDE (__ehdr = 0x10000);
                   PROVIDE (_ehdr = 0x10000);
  /DISCARD/ : { *(.note.GNU-stack) }
}


Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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-Sect...

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 :)

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht 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-Sect...
>

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.