home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <etc.h>
- #include "link.h"
-
-
- #define ALLOC_SYM 10000 // Nombre de symbole alloué par chunk
- /*
- Liste des symboles
- Pour chaque symbole, on retient son module de provenance.
- */
- PUBLIC SYMBOLS::SYMBOLS()
- {
- sym.cur = NULL;
- memset (hash,0,sizeof(hash));
- allocsym();
- }
-
- /*
- Alloue un nouveau buffer d'accumulation pour les symboles
- */
- PROTECTED void SYMBOLS::allocsym()
- {
- LIST_SYMBOL *list = (LIST_SYMBOL*) malloc_err (sizeof(LIST_SYMBOL)
- +ALLOC_SYM*sizeof(SYMBOL),1);
- list->next = sym.cur;
- sym.cur = list;
- sym.nb = 0;
- sym.ptacc = list->alloc;
- sym.lastacc = list->alloc+ALLOC_SYM;
- }
-
- /*
- Ajoute un symbole ou localise.
- Ce symbole est soit publique ou un external (requis).
-
- Retourne le symbole localisé ou ajouté
- */
- PUBLIC SYMBOL *SYMBOLS::add (
- const char *name,
- MODULE *module, // Module qui déclare ce symbole ou NULL.
- SYM_STATUS status,
- int &module_requis, // Contiendra != 0 si on établis que le module
- // en traitement est requis par un autre
- // module vue précédemment.
- // Assume qu'il y a deja une valeure dedans
- int is_common)
- {
- // if (strncmp(name,"__PLT_",6)==0 || strncmp(name,"__GOT_",6)==0){
- // name += 6;
- // }
- //printf (":%s: %d\n",name,status);
- // Recherche le nom
- unsigned hashval = 0;
- const char *pt = name;
- while (*pt != '\0'){
- hashval = (hashval << 1) + *pt++;
- }
- hashval %= 2048;
- SYMBOL **ffind = hash + hashval;
- SYMBOL *find = *ffind;
- while (find != NULL){
- if (strcmp(find->name,name)==0) break;
- find = find->next;
- }
- if (find == NULL){
- // Ajoute a la liste
- if (sym.ptacc == sym.lastacc) allocsym();
- find = sym.ptacc++;
- sym.nb++;
- find->name = alloctxt_add (name);
- find->module = NULL;
- find->next = *ffind;
- *ffind = find;
- find->force = 0;
- find->is_common = 0;
- find->is_dup = 0;
- if (status == SYM_REQUIS){
- find->requis = 1;
- find->defini = 0;
- find->vue_avant = 0;
- }else if (status == SYM_PASUTIL){
- find->requis = 0;
- find->defini = 0;
- find->vue_avant = 0;
- }else{
- find->requis = 0;
- find->defini = 1;
- find->vue_avant = 1;
- find->is_common = is_common;
- find->module = module;
- }
- }else{
- // Deja la
- if (status == SYM_DEFINI){
- if (find->defini){
- // Le symbole est déjà définie
- // On ne l'insere pas dans le hashing et on note
- // qu'il est en double. Si jamais un module doit
- // être chargé et possède un symbole "duplicate"
- // on pourra signale le probleme.
- if (sym.ptacc == sym.lastacc) allocsym();
- find = sym.ptacc++;
- sym.nb++;
- find->name = alloctxt_add (name);
- find->next = NULL;
- find->force = 0;
- find->is_common = 0;
- find->is_dup = 1;
- find->requis = 0;
- find->vue_avant = 0;
- }
- find->module = module;
- find->defini = 1;
- find->is_common = is_common;
- if (find->requis) module_requis = 1;
- }else if (status == SYM_REQUIS){
- find->requis = 1;
- }
- }
- return find;
- }
-
- /*
- Trouve les symboles qui doivent être "demander" au linker.
- On fait ca pour eviter un link multi-passe.
-
- Retourne le nombre de symbole placé dans tb.
- */
- PUBLIC int SYMBOLS::findforce (
- char **tb, // tb peut être NULL
- // Ca permet de les compter
- int maxtb)
- {
- int ret = 0;
- LIST_SYMBOL *list = sym.cur;
- int nbsym = sym.nb;
- while (list != NULL){
- SYMBOL *ptsym = list->alloc;
- for (int i=0; i<nbsym; i++, ptsym++){
- if (ptsym->force){
- if (tb != NULL) tb[ret++] = strdup_err (ptsym->name,1);
- }
- }
- nbsym = ALLOC_SYM;
- list = list->next;
- }
- return ret;
- }
-
- /*
- Présente toute la liste de symbole en mémoire
- */
- PUBLIC void SYMBOLS::dump (FILE *fout)
- {
- LIST_SYMBOL *list = sym.cur;
- int nbsym = sym.nb;
- while (list != NULL){
- SYMBOL *ptsym = list->alloc;
- for (int i=0; i<nbsym; i++, ptsym++){
- fprintf (fout,"%s %d %d %d %d %d\n",ptsym->name,ptsym->requis
- ,ptsym->defini,ptsym->vue_avant
- ,ptsym->is_common,ptsym->force);
- }
- nbsym = ALLOC_SYM;
- list = list->next;
- }
- }
-
-