int find_export_sym(const char *name, int touch) { int name_len = strlen(name); int h = sym_hash(name, name_len); int cur = ex_sym_f[h]; while (cur != -1) { if (strcmp(ex_sym_name[cur], name) == 0) { break; } else { cur = ex_sym_n[cur]; } } if (cur == -1 && touch) { cur = ex_sym_count++; ex_sym_n[cur] = ex_sym_f[h]; ex_sym_f[h] = cur; char * _name = chars + char_count; memmove(_name, name, name_len); char_count += name_len; chars[char_count++] = 0; ex_sym_name[cur] = _name; } return cur; }
void touch_export_sym(const char *name, uintptr_t ptr, uint32_t flags) { int name_len = strlen(name); int h = sym_hash(name, name_len); int cur = ex_sym_f[h]; while (cur != -1) { if (strcmp(ex_sym_name[cur], name) == 0) { // symbol found break; } else { cur = ex_sym_n[cur]; } } // not found, create one if (cur == -1) { cur = ex_sym_count++; ex_sym_n[cur] = ex_sym_f[h]; ex_sym_f[h] = cur; char * _name = chars + char_count; memmove(_name, name, name_len); char_count += name_len; ex_sym_name[cur] = _name; chars[char_count++] = 0; } ex_sym_ptr[cur] = ptr; ex_sym_flags[cur] = flags; }
int sym_insert( struct symTable *st, const char *name, struct Value val ) { int index = sym_hash( name ); struct Symbol *head = st->table[index]; struct Symbol *sb = sym_lookup( st, name ); if( sb != 0 ) { /* the symbol exists, update its value */ /* if the symbol's value type is STRING type, free the memory first */ if( sb->val.type == SB_VAR_STRING ) { free( sb->val.sval ); } sb->val = val; } else { /* create a new symbol and insert it */ struct Symbol *new_sb = (struct Symbol*) malloc( sizeof( struct Symbol ) ); new_sb->name = (char*) malloc( strlen( name ) + 1 ); strcpy( new_sb->name, name ); new_sb->val = val; new_sb->next = head; st->table[index] = new_sb; } return 0; }
int sym_insert_array( struct symTable *st, const char *name, size_t size ) { struct Symbol *sb = sym_lookup( st, name ); if( sb != 0 ) { return -1; } else { size_t i; int index = sym_hash( name ); struct Symbol *head = st->table[index]; struct Symbol *new_sb = (struct Symbol*) malloc( sizeof( struct Symbol ) ); new_sb->name = (char*) malloc( strlen( name ) + 1 ); strcpy( new_sb->name, name ); new_sb->val.type = SB_VAR_ARRAY; new_sb->val.size = size; new_sb->val.aval = (struct Value *) malloc( sizeof( struct Value ) * size ); for( i = 0; i < size; ++ i ) { new_sb->val.aval[i].type = SB_VAR_NUM; new_sb->val.aval[i].dval = 0; } new_sb->next = head; st->table[index] = new_sb; } return 0; }
struct Symbol *sym_lookup( struct symTable *st, const char *name ) { int index = sym_hash( name ); struct Symbol *head = st->table[index]; struct Symbol *sb; for( sb = head; sb != 0 && strcmp( sb->name, name ) != 0; sb = sb->next ) { } return sb; }
static struct sym_entry * ft_get_entry(void * address) { uint hash = sym_hash(address); if (!sym_table[hash].valid) { ft_get_new_entry(hash, address); goto out; } else if (sym_table[hash].address == address) goto out; // FIXME while (sym_table[hash].valid && sym_table[hash].address != address) { hash = (hash + 1) % sym_hash_size; } out: return &sym_table[hash]; }
static int dln_init(const char *prog) { char *file, fbuf[MAXPATHLEN]; int fd; struct exec hdr; struct nlist *syms; if (dln_init_p == 1) return 0; file = dln_find_exe_r(prog, NULL, fbuf, sizeof(fbuf)); if (file == NULL || (fd = open(file, O_RDONLY)) < 0) { dln_errno = errno; return -1; } if (load_header(fd, &hdr, 0) == -1) return -1; syms = load_sym(fd, &hdr, 0); if (syms == NULL) { close(fd); return -1; } sym_tbl = sym_hash(&hdr, syms); if (sym_tbl == NULL) { /* file may be start with #! */ char c = '\0'; char buf[MAXPATHLEN]; char *p; free(syms); lseek(fd, 0L, 0); if (read(fd, &c, 1) == -1) { dln_errno = errno; return -1; } if (c != '#') goto err_noexec; if (read(fd, &c, 1) == -1) { dln_errno = errno; return -1; } if (c != '!') goto err_noexec; p = buf; /* skip forwarding spaces */ while (read(fd, &c, 1) == 1) { if (c == '\n') goto err_noexec; if (c != '\t' && c != ' ') { *p++ = c; break; } } /* read in command name */ while (read(fd, p, 1) == 1) { if (*p == '\n' || *p == '\t' || *p == ' ') break; p++; if (p-buf >= MAXPATHLEN) { dln_errno = ENAMETOOLONG; return -1; } } *p = '\0'; return dln_init(buf); } dln_init_p = 1; undef_tbl = st_init_strtable(); close(fd); return 0; err_noexec: close(fd); dln_errno = DLN_ENOEXEC; return -1; }