GNU LD: Wie überschreibt man einen Symbolwert (eine Adresse), der durch das mit -T definierte Linkerskript definiert ist

8

Mein Anwendungsfall ist wie folgt:

  • Ich verwende ein typisches SDK, das mit Makefile-basierten Projekten geliefert wird
  • Ich glaube, der Linker ist gepatcht gcc. gcc --version gibt mir 4.3.4
  • SDK definiert das Linker-Skript (lasst es Linker.ld nennen)
  • Linker.ld enthält LinkerMemMap.cfg, das die absoluten Adressen für verschiedene Abschnitte im verknüpften ELF-Bild
  • definiert
  • SDK stellt Applikationsvorlagen basierend auf Makefiles (GNU Make 3.81) bereit und macht sich selbst
  • Wenn in der vom SDK bereitgestellten Makefile-Vorlage gcc aufgerufen wird, wird Linker.ld wie folgt mit der Befehlszeilenoption -T angegeben:

gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

Meine Anforderung lautet wie folgt:

  • Ich möchte die Abschnitte wie in Linker.ld definiert verwenden und die Speicherzuordnung wie LinkerMemMap.cfg verwenden, aber ein bestimmtes Symbol (nennen wir es SYMBOL_RAM_START), das in LinkerMemMap.cfg
  • definiert ist, optimieren

Was funktioniert:

  • Ich habe in dem Makefile versucht, vor dem Verknüpfen des endgültigen ELF-Abbilds die LinkerMemMap.cfg (die von Linker.ld enthalten ist) in das Buildverzeichnis zu kopieren und es zu patchen, um SYMBOL_RAM_START neu zu definieren. Dieses funktioniert , da der Linker zuerst nach den Linker-Skripten und den Dateien sucht, die von den Linker-Skripten im aktuellen Ordner enthalten sind.

Was nicht:

  • Leider halten unsere Stakeholder die oben genannte Methode für zu riskant und zu komplex, um sie zu verstehen. Ich möchte den Symbolwert in der Linker-Befehlszeile mit etwas wie folgt überschreiben:

    1. gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections,--defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

    2. gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

    3. gcc $(OBJS) -l$(Lib1) -l$(Lib2) --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

Keins von diesen scheint irgendeine Auswirkung auf das verknüpfte Bild zu haben, das vom Linker erzeugt wird.

  • Kann --defsym die Symbole überschreiben, die durch Linksskript definiert sind, das mit -T?
  • angegeben wurde
  • Könnte jemand von euch bitte sehen, was mache ich hier falsch?
Aravind 05.04.2012, 16:43
quelle

1 Antwort

12

Während ich darauf gewartet habe, dass jemand antwortet, habe ich das Problem gelöst. Es gibt einige Probleme mit dem Problem hier und ich dachte daran, meine Ergebnisse für jemanden zu erklären, der den gleichen Fehler machen könnte.

Zuerst Alle Optionen, die an den Linker übergeben werden sollen, müssen mit -Xlinker oder mit -Wl angegeben werden. Daher werden sowohl 2 als auch 3 im obigen Fall nicht funktionieren. Die korrigierten 2 und 3 wären wie folgt:

  1. Ist schon richtig

  2. gcc $(OBJS) -l$(Lib1) -l$(Lib2) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -o$(OUTPUT).elf

  3. gcc $(OBJS) -l$(Lib1) -l$(Lib2) -Xlinker --defsym=SYMBOL_RAM_START=$(VALUE_TO_OVERRIDE) -nostdlib -lgcc -L$(library_path) -g -msmall-mode -mconst-switch-tables -mas-mode -mno-initc -Wl,--start-group,--end-group,-T,$(PATH_TO_Linker.ld),--gc-sections -o$(OUTPUT).elf

Jetzt für den Fall der Optionen 1 & amp; 2 oben, --defsym kommt nach dem Linker-Skript und SYMBOL_RAM_START wurde bereits vom Linker-Skript definiert. Es überschreibt es. Der überschriebene Wert wird jedoch nicht verwendet, da die Abschnitte bereits definiert wurden, da das Linker-Skript bereits verwendet wurde.

Für den Fall der obigen Option 3 wurde das SYMBOL_RAM_START definiert, bevor das Linker-Skript vom Linker gelesen wurde. Daher wird beim Analysieren des Linker-Skripts der im Skript angegebene Wert überschrieben.

Lösung:

Damit dies funktioniert, muss das Linker-Skript das Symbol SYMBOL_RAM_START wie folgt initialisieren:

SYMBOL_RAM_START = DEFINIERT ( SYMBOL_RAM_START )? SYMBOL_RAM_START : DEFAULT_VALUE;

Wenn im obigen Linker-Skript das SYMBOL_RAM_START vor dem Einfügen des Linker-Skripts definiert wurde (wie oben in Option 3 gezeigt), funktionierte es. Aber am Ende musste ich das Linkerscript patchen.

Diese Lösung überschreibt das Symbol nicht wirklich, bietet aber eine Möglichkeit, ein Symbol so zu definieren, dass es überschrieben werden kann.

    
Aravind 11.04.2012, 17:02
quelle

Tags und Links