/* should NOT add ANY DUPLICATES */ int add_list_to_head( struct bl_head *head, struct bl_rule *first, struct bl_rule *last, int truncate, int expire_limit) { struct bl_rule *p; unsigned int expire_end=0; if (!head || !first || !last) return -1; /* may I add to this list? */ if (head->flags&BL_READONLY_LIST) { LM_CRIT("list is readonly!!!\n"); return -1; } LM_DBG("adding to bl %.*s %p,%p\n", head->name.len, head->name.s, first,last); /* for expiring lists, sets the timeout */ if (head->flags&BL_DO_EXPIRE) { if (expire_limit==0) { LM_CRIT("expire is zero!!!\n"); return -1; } expire_end = get_ticks() + expire_limit; for(p = first ; p ; p = p->next) p->expire_end = expire_end; } /* truncate? -> just do reload */ if (truncate) return reload_permanent_list( first, last, head); /* get list for write */ lock_get(head->lock); while(head->count_write){ lock_release( head->lock ); sleep_us(5); lock_get( head->lock ); } head->count_write = 1; while(head->count_read){ lock_release( head->lock ); sleep_us(5); lock_get( head->lock ); } lock_release( head->lock ); rm_dups( head, &first, &last); if (first==NULL) goto done; if (head->first==NULL) { head->last = last; head->first = first; } else if ( !(head->flags&BL_DO_EXPIRE) ) { head->last->next = first; head->last = last; } else if( head->first->expire_end >= expire_end){ last->next = head->first; head->first = first; } else if(head->last->expire_end <= expire_end){ head->last->next = first; head->last = last; } else { for(p = head->first ; ; p = p->next) if( p->next->expire_end >= expire_end) break; last->next = p->next; p->next = first; } done: head->count_write = 0; return 0; }
static void fetch_symtab(Elf *elf, char *filename, mod_info_t *module) { Elf_Scn *scn = NULL, *sym = NULL; GElf_Word strndx = 0; size_t i, nsyms, nfuncs; Elf_Data *symdata; nltype *nl, *npe; while ((scn = elf_nextscn(elf, scn)) != NULL) { GElf_Shdr shdr; if (gelf_getshdr(scn, &shdr) == NULL) continue; if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { GElf_Xword chk = shdr.sh_size / shdr.sh_entsize; nsyms = (size_t)(shdr.sh_size / shdr.sh_entsize); if (chk != (GElf_Xword) nsyms) { (void) fprintf(stderr, "%s: can't handle" "more than 2^32 symbols", cmdname); exit(ERR_INPUT); } strndx = shdr.sh_link; sym = scn; } /* * If we've found a real symbol table, we're done. */ if (shdr.sh_type == SHT_SYMTAB) break; } if (sym == NULL || strndx == 0) { (void) fprintf(stderr, "%s: missing symbol table in %s\n", cmdname, filename); exit(ERR_ELF); } if ((symdata = elf_getdata(scn, NULL)) == NULL) { (void) fprintf(stderr, "%s: can't read symbol data from %s\n", cmdname, filename); exit(ERR_ELF); } if ((npe = nl = (nltype *) calloc(nsyms, sizeof (nltype))) == NULL) { (void) fprintf(stderr, "%s: can't alloc %x bytes for symbols\n", cmdname, nsyms * sizeof (nltype)); exit(ERR_ELF); } /* * Now we need to cruise through the symbol table eliminating * all non-functions from consideration, and making strings * real. */ nfuncs = 0; for (i = 1; i < nsyms; i++) { GElf_Sym gsym; char *name; (void) gelf_getsym(symdata, i, &gsym); name = elf_strptr(elf, strndx, gsym.st_name); /* * We're interested in this symbol if it's a function */ if (is_function(elf, &gsym)) { npe->name = name; npe->value = gsym.st_value; npe->size = gsym.st_size; npe->info = gsym.st_info; npe++; nfuncs++; } if (strcmp(name, PRF_END) == 0) module->data_end = gsym.st_value; } if (npe == nl) { (void) fprintf(stderr, "%s: no valid functions in %s\n", cmdname, filename); exit(ERR_INPUT); } /* * And finally, sort the symbols by increasing address * and remove the duplicates. */ qsort(nl, nfuncs, sizeof (nltype), cmp_by_address); rm_dups(nl, &nfuncs); module->nl = nl; module->nfuncs = nfuncs; }