Autor Thema: Problem beim Linken vom C++ Kernel  (Gelesen 6820 mal)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« am: 07. October 2008, 13:04 »
Ich wollte ein C++ Kernel zum laufen bringen, doch mit dieser Fehlermeldung kann ich nicht richtig deuten, weil ich mich mit dem Linken nicht so auskenne.

Die Fehlermeldung:
ld -T Link.ld -o Kernel.bin
Video.o:Video.cpp:(.text+0x294): undefined reference to `__ZN6CVideo6memcpyEPvPKvj'
Video.o:Video.cpp:(.text+0x2ce): undefined reference to `__ZN6CVideo6memsetEPvij'
Video.o:Video.cpp:(.text+0x309): undefined reference to `__ZN6CVideo6memsetEPvij'
Die Datei Link.ld:
/*Link.ld*/
OUTPUT_FORMAT("binary")
INPUT (kernel32.obj Kernel.o Video.o)
ENTRY(start)
SECTIONS
{
.text 0x10200 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
__CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors) LONG(0) __CTOR_END__ = .;
__DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors) LONG(0) __DTOR_END__ = .;
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}

.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}

end = .; _end = .; __end = .;
}
Die anderen Dateien sind die aus dem c++ Kernel Tutorial.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 07. October 2008, 13:28 »
der linker beschwert sich, dass er
Video::memcpy
Video::memset
nicht finden kann, du sie aber irgend wo benutzen willst.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 07. October 2008, 17:31 »
Ja hab den Fehler gefunden, hab vergessen Die Funktionen in die Klasse einzubinden (Klasse::Funktion).
Danke.
Ich wüsste gern noch etwas anderes gibt es eine Möglichkeit, dass eine C/C++ Funktion zwingen kann mit IRET statt RET zurückspringt, dass ganze währe für Interrupts sehr nützlich. Vielleicht gibt es ja eine Möglichkeit.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 07. October 2008, 18:19 »
Schreib einen Stub in Assembler, der dann deine C-Funktion aufruft.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 07. October 2008, 18:47 »
Ich weis nicht genau, was ‘Stub‘ ist, aber ich schätze du meinst dass:
Int_xy:
call funktion  ;funktion ist eine c Funktion
        iret
OK, das kann man machen. Darauf bin ich eigentlich auch gekommen, aber ich hab mir gedacht, dass es Vielleich eine andere Möglichkeit dazu gibt, weil für den Compiler das keine große Schwierigkeit sein sollte.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 08. October 2008, 09:08 »
Du willst das sowieso haben, du wirst nämlich im allgemeinen für alle Interrupts denselben Handler aufrufen wollen. Jetzt gibt es da aber beispielsweise Exceptions mit Errorcode und welche ohne. Bei denen ohne willst du noch ein push 0 machen, damit dein Stack einheitlich aussieht. Und mit der Zeit kommt da noch mehr Zeug rein. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 10. October 2008, 17:43 »
Ich sehe schon, dass es mit C/C++ auch nicht ganz so einfach ist.
Jetzt hab die IDT in c realisiert, jedoch hab ich da noch ein Problem mit globalen Funktionen.
Ich hab eine Test Funktion in asm geschrieben:
global  int00

...

int00:
iret
und in der cpp Datei auch deklariere
extern void int00();und mit (unsigned int) int00 verwende ich das.
Und im Linkscript hab ich auch
ENTRY(int00)hinzugefügt (ich weis nicht, ob das erforderlich ist)

aber der Linker prangert folgendes an: undefined reference to '__Z5int00v'Wo muss ich den alles die Funktion hinschreiben

Wie muss ich das den richtig machen.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 10. October 2008, 19:46 »
das liegt am C++
wenn du asm funkitonen includen willst, musst du das mit
extern "c" void int00();machen. ( oder im asm die labels nach C++-Standard benennen  :wink: )

Das 'entry(int00)' ist falsch. es würde bedeuten, dass deine
objekt-datei(kernel) mit deiner int00-Funkiton gestartet werden soll.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 10. October 2008, 21:11 »
Zitat
extern "c" void int00();
Geht nicht, er meckert folgendes:
language string '"c"' not recognized
Zitat
oder im asm die labels nach C++-Standard benennen
wie macht man das?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 10. October 2008, 21:33 »
sry.
du musst das c groß schreiben C.

Zitat
Zitat
oder im asm die labels nach C++-Standard benennen
wie macht man das?
das hab ich nicht wirklich ernst gemeint, ich bin auch nicht sicher ob es reicht die labels so zu benennen:
__Z5int00v
wie genau sich das zusammen setzt weiß ich nicht, aber es sind unteranderem die parametr die übergeben werden mit eingearbeitet.
« Letzte Änderung: 10. October 2008, 21:44 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 11. October 2008, 10:52 »
Es reicht definitiv die Labels so zu benennen wie in der Fehlermeldung des Linkers angegeben. Das ganze nennt sich C++ name mangling und ist Compilerabhängig und eben nicht im C++ Standard spezifiziert. Es ist aber in der bzw. einer der gcc ABI(s) genau beschrieben wie gcc das macht (siehe hier), aber ich würde dir eher raten einfach den richtigen Labelnamen aus den Linkerfehlermeldungen zu entnehmen, dass geht einfach als sich über das ganze Gedanken zu machen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 11. October 2008, 12:09 »
Ja geht jetzt.
Danke    :-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 11. October 2008, 12:10 »
Wie wäre es damit, einfach bei extern "C" zu bleiben anstatt sich aus Fehlermeldungen was zusammenzubauen? Kommt mir irgendwie wesentlich sauberer vor...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 11. October 2008, 14:13 »
extern "C" ist nicht in jedem Kontext verwendbar. Es funktioniert (zumindest unter g++) nicht für Memberfunktionen (auch nicht für statische).
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 11. October 2008, 14:57 »
Die Frage ist, ob man es da braucht oder ob man nicht besser eine Wrapperfunktion schreibt. Assembler ist nunmal nicht objektorientiert.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen