Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: rizor am 23. October 2009, 18:01

Titel: linker findet libgcc-methoden nicht
Beitrag von: rizor am 23. October 2009, 18:01
Nabend zusammen,

ich habe mal wieder ein Problem mit der libgcc.
LD meldet folgende Fehler:
/home/rizor/Desktop/projects/os-development/trunk/libc/libc.lib(printf.c.o): In function `printf_value':
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:213: undefined reference to `__umoddi3'
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:214: undefined reference to `__udivdi3'
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:312: undefined reference to `__stack_chk_fail'

Ich binde die libgcc mit ein.
Der Code, der diese Fehler wirft sieht wie folgt aus:
div64(val , args->base , &rest);
div64:
__asm__("div %%ecx\n\t"
"xchg %%ebx, %%eax\n\t"
"div %%ecx\n\t"
"xchg %%edx, %%ebx"
: "=A"(quot), "=b"(r)
: "a"(high), "b"(low), "c"(y), "d"(0)
);

if (rest)
*rest = r;

Der Stack_chk_fail wird einfach durch ein return retval ausgelöst.
retval ist ein int, der immer wieder hochgezählt wird

Den Fehler finde ich leider nicht
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: kevin am 23. October 2009, 18:24
Sicher, dass du die libgcc einbindest? Hast du beim ld-Aufruf auch mal ein --start-group ... --end-group um die Bibliotheken außenrum probiert, falls er es sonst in der falschen Reihenfolge machen würde?
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: MNemo am 23. October 2009, 18:36
Vermutlich bindest du die falsche Version der libgcc ein. Du brauchst die für 32-Bit Code(`gcc -m32 --print-libgcc-file-name`). In der 64-Bit version gibt es die Funktionen nicht.

BTW bezweifle ich, dass der ASM Code für diese Fehler verantwortlich ist.

__stack_chk_fail: sieh nach stack-protector aus ('-fno-stack-protector').
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: rizor am 24. October 2009, 14:59
Das mit dem --start-grupt hat geholfen.
Das Problem mit dem __stack_chk_fail besteht weiterhin.
Ich kompiliere alles mit -fno-stack-protector
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: rizor am 25. October 2009, 18:38
Hier ist mal die Methode, da ich den Fehler nicht finde.
Würde mich aber wundern, wenn es da ein Problem gibt.

/*
* This method prints a uint64_t with a given base
* @param val - the uint64_t-value which will be printed
* @param arg - the struct args pointer
* @return the number of printed chars
*/
int printf_value(uint64_t val , args_p args){
//the maximum is 64 (64-bit)
int rest_width , req_width = 0 , retval = 0;
int i;
char value_c[65];
char *val_mov = value_c + 64;
char *digits;
char sgn[1];
char prefix[3];
uint32_t rest;

//prepare the char-arrays
memset(value_c , 0 , 65 * sizeof(char));
sgn[0] = '\0';
memset(prefix , 0 , 3 * sizeof(char));

//check if the base is correct
if((args->base < 2) && (args->base > 16))
return 0;

//get the right digits
digits = digits_small;
if(args->flags & FLAG_BIG_CHARS)
digits = digits_big;

//set the value_c to print it later and get the requiered width of the print
do{
val = div64(val , args->base , &rest);
*val_mov-- = digits[rest];
req_width++;
}while(val > 0);

//configure the prefix
if(args->flags & FLAG_PRINT_PREFIX){
switch(args->base){
case 2 : req_width += 2;
prefix[0] = 'b';
prefix[1] = 'i';
prefix[2] = '\0';
case 16 : req_width += 2;
if(args->flags & FLAG_BIG_CHARS){
prefix[0] = '0';
prefix[1] = 'X';
prefix[2] = '\0';
}
else{
prefix[0] = '0';
prefix[1] = 'x';
prefix[2] = '\0';
}
break;
case 8 : req_width++;
break;
default : break;
}
}

//check the sign and configure it
if(args->flags & FLAG_NEGATIVE_DEC){
sgn[0] = '-';
req_width++;
}
else if(args->flags & FLAG_PRINT_SIGN){
sgn[0] = '+';
req_width++;
}
else if(args->flags & FLAG_SPACE_POSITIVE){
sgn[0] = ' ';
req_width++;
}

//no sign
if(*prefix != '\0'){
//print the prefix
while(*prefix){
con_put_char(prefix[i++]);
retval++;
}
}
//print the sign
else{
//print the sign
if(*sgn){
con_put_char(*sgn);
retval++;
}
}

//check if it is needed to print the fill-char
if(args->print_width > req_width){
//print the zeros
if(args->flags & FLAG_ZEROFILL){
//print the zerofill
while(args->print_width-- > req_width){
con_put_char('0');
retval++;
}

//print the value
while(*val_mov){
con_put_char(*val_mov++);
retval++;
}
}
//print firs the sign and after that print the spacing
else if(args->flags & FLAG_LEFT_ORIGIN){
//print the value
while(*val_mov){
con_put_char(*val_mov++);
retval++;
}

//print the zerofill
while(args->print_width-- > req_width){
con_put_char(' ');
retval++;
}
}
}
else
while(*val_mov){
con_put_char(*val_mov++);
retval++;
}

return retval;
}

Kann einer von euch da einen Fehler finden?
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: DerHartmut am 26. October 2009, 13:10
Welchen Fehler genau? Die von oben?

Normalerweise müsste mit den Flag -fno-stack-protector auch der Fehler verschwinden. Ansonsten erstellst du einfach ein Stub dieser Funktion (ist jetzt allerdings nicht die bevorzugte Methode ;))
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: rizor am 26. October 2009, 13:26
Hab den Fehler eben gefunden.
Es fehlt ein break in dem switch....
Jetzt funktioniert alles
Titel: Re: linker findet libgcc-methoden nicht
Beitrag von: DerHartmut am 28. October 2009, 00:03
Das sind die fiesesten Fehler ;-)