Mémoire dynamique sans bibliothèque

OS from scratch

Le problème exposé dans ce sujet a été résolu.

Bonjour les agrumes,

Ce weekend je me suis laissé tenter par le tutoriel de IKnow pour concevoir son OS from scratch. C’est plus dans l’idée de m’amuser et comprendre le fonctionnement d’un OS (son amorçage) qu’en concevoir un.

Le souci d’une telle démarche c’est qu’on repart de zéro, on doit construire nous même les bibliothèques standards. En l’occurence, j’aimerai pouvoir déclarer une chaîne de caractères avec une taille fixe et dynamique (on parle ici d’un monde parallèle sans la fonction malloc() … OMG!).

Voici une fonction que j’ai codé pour afficher textuellement le code d’un char :

string ordChr(char ch) {
    string buffStr = "\x00\x00\x00\x00";
    string alpha = "0123456789";
    uint16 iBuffStr = lenChr(ch)-1;
    while(ch > 0 && iBuffStr >= 0 && iBuffStr < 4) {
        buffStr[iBuffStr] = alpha[ch % 10];
        ch = (ch - (ch % 10)) / 10;
        --iBuffStr;
    }
    return buffStr;
}

Si je déclare ma variable telle que string buffStr; ou même string buffStr[4];, ça provoque un buffer overflow. Puis l’idéal ce serait de pouvoir avoir dans certain cas une variable de taille dynamique, notamment j’ai une fonction readStr qui attend X caractères de la part de l’utilisateur. Comment faire ?

Peut-être en passant par l’assembleur, via cette fonction :

#include "system.h"

uint8 inPortB(uint16 _port) {
    unsigned char rv;
    __asm__ __volatile__ ("inb %w1,%0" : "=a" (rv) : "dN" (_port));
    return rv;
}

void outPortB(uint16 _port, uint8 _data) {
    __asm__ __volatile__ ("outb %%al,$0x80" : : "dN" (_port), "a" (_data));
}

Comment dire ? Je suis une bille en ASM :p bidouiller et trouver de la docs sur le sujet ça va.

Une petite idée ? Merciii et bon weekend.

Edit : le sujet avait sauté à cause des caches de ré-édition … bizaremment ça n’arrive pas tout le temps.

Edit2 : pour voir les sources de mon GloomOS. :D

+0 -0

Je ne suis pas sur de saisir exactement ce que tu veux faire, mais, à priori, indépendemment du langage, tu as besoin de mémoire.

la première approche c’est de traiter les caractères un par un, à la volée: de cette façon, tu renvoie le problème de la mémoire sur ce qui affiche le résultat. Localement tu n’a besoin de ne mémoriser qu’un caractère et son décodage.

Seconde approche: au début de ta fonction tu évalue la taille de l’entrée, et tu crée une variable assez grande pour stocker le plus grand résultat possible, ce qui signifie disposer d’une pile (la zone mémoire où sont placées les allocations locales) assez grande (et aussi de disposer d’un lanage sachant gérer des tableaux de taille variable, VLA, mais, au pire, dans un contexte éducatif, réserver de la place sur la pile, ça peut se faire en assembleur).

Troisème approche: tu veux de la mémoire dynamique ? Implémente la. Tu dis à ton OS, d’une façon ou d’une autre, combien il y a de mémoire, il suffit qu’il tienne à jour une liste de la mémoire qu’il a attribuée, et, quand tu lui demande de la mémoire, il réserve une partie pas encore attribuée pour toi, et, quand tu n’en as plus besoin, tu lui dit, pour qu’il puisse l’attribuer à quelqu’un d’autre.

Merci Jacen pour ta réponse, des bons points à creuser ! :)

Je ne suis pas sur de saisir exactement ce que tu veux faire, mais, à priori, indépendemment du langage, tu as besoin de mémoire.

Jacen

Mon problème c’est surtout que l’allocation de chars est plutôt destabilisante. Si on prend la solution proposé sur StackOverflow :

void foo(char *buf, int count) {
    for(int i = 0; i < count; ++i)
        buf[i] = i;
}

int main() {
    char arr[10] = {0};
    foo(arr, 10);
}

A la compilation ça ne fonctionne pas, j’ai une erreur :

gcc x86

référence indéfinie vers « __stack_chk_fail_local »

Jusqu’à présent je n’ai déclaré que des chaînes de caractères et la seule manière pour moi de déclarer une taille est la suivante :

string mavar;
mavar = "\x00\x00\x00\x00\x00"; // 5 caractères

Pas moyen même que je fasse un type particulier en chars :

char mavar[10];

La simple déclaration de taille suffit pour qu’il me rappelle à l’ordre que "__stack_chk_fail_local" est indéfini … sauf que je ne sais pas ce que c’est ?!

D’où ce sujet … par quel bout le prendre ? Y’a peut-être une règle en C dont je n’ai pas connaissances.

Ca ressemble pas à une règle du C, mais à une règle de GCC, liée probablement à une option comme -fstack-protector

Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than or equal to 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits. Only variables that are actually allocated on the stack are considered, optimized away variables or variables allocated in registers don’t count.

tu as, de façon notable, le problème avec un buffer de plus de 8 bytes. Si tu n’as plus de libc, tu n’as probablement plus de libgcc non plus, et c’est probablement là que le mécaniqme est implémenté, d’où le undefined reference. Vérifie tes options de compilation, et s’il n’y a rien de relatif à ça, essaye d’ajouter -fno-stack-protector (habituellement, GCC a des options en fno pour annuler les options de base).

Attention, j’ai juste fait une recherche google pour voir à quoi peut être liée la fonction manquante, j’ai pas tout vérifié dans les détails, mon analyse peut être erronée.

Merci pour ta réponse Jacen mais ça n’a pas suffit.

J’ai pû bypasser la protection en déclarant une méthode vide :

void __stack_chk_fail_local() {}

Mais le mieux ce serait de la recoder au propre en suivant cet exemple et les libs liés à celle-ci.

Elle est importante mine de rien. ;)

Edit : je laisse le sujet en "non résolu", au cas où j’ai encore quelques problématiques d’implémentations avec la création d’une lib pour gérer la mémoire. Merci.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte