jak dat procedure abs.adresu v C v Yagarto?

Jan Waclawek konfera na efton.sk
Úterý Prosinec 7 10:09:28 CET 2010


Ale ale, pan kolega. Viem, ze mate na GNU prostriedky slabost, ale trocha mierenej kritiky nemoze skodit.

>> GNU linker je bohuzial nie najlepsie zdokumentovany a je v nom vela sedivych miest, ktore sa naviac v case (s roznymi verziami binutils) tak trocha menia :-(
>>
>Je zdokumentovany viac ako dostatocne, dokumentacia je jednoducha a 
>prehladna. Vola sa "The GNU linker" a cely popis linker skriptu od 
>jednoduchsiemu k zlozitejsiemu s mnohymi prikladmi zabera celych 37 
>stran, 


Velmi rad by som urobil pokus: niekomu, kto este linker script pre ld nevidel, dat k dispozicii tu dokumentaciu s mnohymi prikladmi a sledovat, ako taky fungujuci linker script vytvori. Ale povedzme ze to je len taka hypoteticka zalezitost, prejdime ku konkretnostiam.


>"Sedive miesta" su len tam, kde sa niekto pokusa sponovat veci na doraz, 
>snaziac sa interpretovat jednotlive casti po svojom, pripadne pouzivat 
>riesenia najdene na Google, ktore niekomu fungovali v minulosti, napriek 
>tomu ze ich pouzitie dokumentacia nezmienuje, pripadne od nich odradza. 
>Taketo vlastnosti sa volaju "nedokumentovane vlastnosti" a autori 
>programu maju pravo taketo vlastnosti upravovat a odstranovat, a ten kto 
>ich pouziva ma pravo sa cudovat, ale nema pravo sa stazovat. Medzi 
>taketo typicky patri aj pouzivanie rozsirujucich  linker skriptov k 
>preddefinovanym skriptom (bez parametra -T).


No, vynikajuce, presne toto je ukazka takeho sediveho miesta - a vobec to nie je tak, ako pisete v predchadzajucej kapitole. Taketo skripty sa volaju implicitne, a je im venovana v dokumentacii kapitola 3.11 (http://sourceware.org/binutils/docs/ld/Implicit-Linker-Scripts.html#Implicit-Linker-Scripts -uznavam, ze nie prilis rozsiahla), obsahujuca aj nasledovnu jazykovu perlu, ukazujucu typicky arogantny pristup pisatelov GNU "dokumentov":

"Any input files read because of an implicit linker script will be read at the position in the command line where the implicit linker script was read."

Dalej sa spominaju v kapitole 2.1:

"If the linker cannot recognize the format of an object file, it will assume that it is a linker script. A script specified in this way augments the main linker script used for the link (either the default linker script or the one specified by using -T). This feature permits the linker to link against a file which appears to be an object or an archive, but actually merely defines some symbol values, or uses INPUT or GROUP to load other objects. Note that specifying a script in this way merely augments the main linker script; use the -T option to replace the default linker script entirely. See Scripts. "

Nie je to teda "nedokumentovana vlastnost", nie je pravda ze sa o pouzivani implicitnych scriptov "dokumentacia nezmienuje", ba dokonca nie je ani pravda, ze by sa "od nich odradzalo". Na druhej strane, je pravda, ze ich pouzitie je sprevadzane roznymi problemami, na cele so zmenou spravania pri zmene verzie linkera.

---

Dalej, ked uz bol spomenuty prepinac -T, tak z kapitoly 2.1:
"For options whose names are a single letter, option arguments must either follow the option letter without intervening whitespace, or be given as separate arguments immediately following the option that requires them. "
dalej
"-T scriptfile
--script=scriptfile
    Use scriptfile as the linker script. This script replaces ld's default linker script (rather than adding to it), so commandfile must specify everything necessary to describe the output file. See Scripts. If scriptfile does not exist in the current directory, ld looks for it in the directories specified by any preceding -L options. Multiple -T options accumulate. "

Takze si vytvorim linker skript nazvany "data" a skusim podla predpisu ho pouzit s "-Tdata":
c:\tmp>avr-gcc t.c -Os -DF_CPU=14745600UL mmcu=atmega2561 -Wa,-adhlns=t.lst -Wl,-Map=t.map,--cref -o t.elf t1.c "-Wl,-Tdata"
c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/../../../../avr/bin/ld.exe: invalid hex number `--library=gcc'

... co nam okrem ineho ukaze aj to, ako pekne ilustrativne su niektore chybove hlasky linkera (tato je este z tych lepsich).

---

Dalej, v povodnej odpovedi spominany prepinac --section-start. Znova sa nejedna o "nedokumentovanu vlastnost" ci "dokumentacia od nich odradza", v kapitole 2.1 sa jasne pise:
--section-start=sectionname=org
    Locate a section in the output file at the absolute address given by org. You may use this option as many times as necessary to locate multiple sections in the command line. org must be a single hexadecimal integer; for compatibility with other linkers, you may omit the leading `0x' usually associated with hexadecimal values. Note: there should be no white space between sectionname, the equals sign (“<=>”), and org. 

Takze majme subory t.c:
int a __attribute__((__section__("somedata")));
int c __attribute__((__section__("xyz")));
int main(void){}

a t1.c:
int b __attribute__((__section__("somedata")));
int d __attribute__((__section__("xyz")));

Spustime:
c:\tmp>avr-gcc t.c -Os -DF_CPU=14745600UL -mmcu=atmega2561 -Wa,-adhlns=t.lst -Wl,-Map=t.map,--cref -o t.elf t1.c "-Wl,--section-start,somedata=0x1234"
c:\tmp>

(tie premenne v section "xyz" su tam cvicne, aby sme videli, co sa stane, ak trebars urobime preklep v nazve section)

Pozrieme do t.map, a niekde ku koncu najdeme:
LOAD linker stubs

somedata        0x00001234        0x2
 somedata       0x00001234        0x2 C:\Users\OM7ZZ\AppData\Local\Temp/cceyWwRc.o
                0x00001234                a

Super, zafungovalo to! No ale kde su ostatne premenne?


.data           0x00800200        0x0 load address 0x00000116
                0x00800200                PROVIDE (__data_start, .)
 *(.data)
 .data          0x00800200        0x0 c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr6/crtm2561.o
 .data          0x00800200        0x0 C:\Users\OM7ZZ\AppData\Local\Temp/cceyWwRc.o
 .data          0x00800200        0x0 C:\Users\OM7ZZ\AppData\Local\Temp/ccutojSM.o
 .data          0x00800200        0x0 c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/avr6\libgcc.a(_exit.o)
 .data          0x00800200        0x0 c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/avr6\libgcc.a(_clear_bss.o)
 *(.data*)
 *(.rodata)
 *(.rodata*)
 *(.gnu.linkonce.d*)
                0x00800200                . = ALIGN (0x2)
                0x00800200                _edata = .
                0x00800200                PROVIDE (__data_end, .)
                0x00800200                . = ALIGN (0x1)
                0x00800200                PROVIDE (__start_xyz, .)

xyz             0x00800200        0x4 load address 0x00000116
 xyz            0x00800200        0x2 C:\Users\OM7ZZ\AppData\Local\Temp/cceyWwRc.o
                0x00800200                c
 xyz            0x00800202        0x2 C:\Users\OM7ZZ\AppData\Local\Temp/ccutojSM.o
                0x00800202                d
                0x00800204                PROVIDE (__stop_xyz, .)

somedata.1      0x00800204        0x2 load address 0x0000011a
 somedata       0x00800204        0x2 C:\Users\OM7ZZ\AppData\Local\Temp/ccutojSM.o
                0x00800204                b


Hummm. Takze pre premennu b si linker vytvoril iny input section a iniciativne ho hodil medzi .data (t.j. *inicializovane* premenne); naviac tam dal bez akehokolvek varovania aj ten nas "preklep", t.j. premenne c a d.

Urobme dalsi pokus. Pridajme do t.c nejaku neinicializovanu globalnu premennu, napr.
int k;

c:\tmp>avr-gcc t.c -Os -DF_CPU=14745600UL -mmcu=atmega2561 -Wa,-adhlns=t.lst -Wl,-Map=t.map,--cref -o t.elf t1.c "-Wl,--section-start,somedata=0x1234"
c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/../../../../avr/
bin/ld.exe: warning: dot moved backwards before `.bss'
c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/../../../../avr/
bin/ld.exe: warning: dot moved backwards before `.bss'
c:/program files/atmel/avrtools/winavr/bin/../lib/gcc/avr/4.2.2/../../../../avr/
bin/ld.exe: warning: dot moved backwards before `.bss'

c:\tmp>

Velmi vtipne.


No a v tomto duchu by sa dalo pokracovat aj dalej.

---

>Takze najjednoduchsi postup za 2 minuty:

S tymto samozrejme musim na 100% suhlasit, ten postup nema chybu. 



>Takze netreba sa nechat vyplasit a znechutit. Je to jednoduche.
>

Vyplasit sa netreba aj ked je to znechucujuce a v mnohych pripadoch vobec nie jednoduche... ;-)

wek






Další informace o konferenci Hw-list