📄 dld_memmgr.c
字号:
return NULL;}struct memmgr *memmgr_find_by_addr(struct list_head *list, u32 base, u32 size){ struct memmgr *mem; /* * search in local list */ if (list && (list != &g_memlist)) { memmgr_for_each(mem, list) { if ((base >= mem->base) && (base + size <= mem->base + mem->size)) return mem; /* found! */ } } /* * search in global list */ memmgr_for_each(mem, &g_memlist) { if ((base >= mem->base) && (base + size <= mem->base + mem->size)) return mem; /* found! */ } /* not found */ return NULL;}struct memmgr *memmgr_find_by_name(struct list_head *list, char *name){ struct memmgr *mem; /* * search in local list */ if (list && (list != &g_memlist)) { memmgr_for_each(mem, list) { if (!strcmp(mem->name, name)) return mem; /* found! */ } } /* * search in global list */ memmgr_for_each(mem, &g_memlist) { if (!strcmp(mem->name, name)) return mem; /* found! */ } /* not found */ return NULL;}/* * memory space */#define spaceof(a) \ (((a) < DSP_MEM_SIZE) ? SPACE_INTERNAL : \ ((a) < VECTPG_BASE) ? SPACE_EXTERN : \ SPACE_VECTPG)int space_find_by_addr(u32 addr, u32 size){ int space = spaceof(addr); if (spaceof(addr + size - 1) == space) return space; else return SPACE_CROSSING;}void memmgr_occupy_kernel(struct list_head *scnlist){ /* * use only g_memlist */ struct section *scn; struct memmgr *mem; /* * search the highest address of the area allocated * for kernel sections */ section_for_each(scn, scnlist) { u32 scnend; if (scn->size == 0) continue; mem = memmgr_find_by_addr(NULL, scn->vaddr, scn->size); if (mem == NULL) continue; scnend = scn->vaddr + scn->size; if (scnend > mem->seg_base) mem->seg_base = scnend; } memmgr_for_each(mem, &g_memlist) { struct memseg *seg;#if 0 u32 a; /* * decide segment align according to the memory size */ mem->seg_align = 1; a = mem->base + mem->size - mem->seg_base; while (a >>= 1) { mem->seg_align <<= 1; } mem->seg_align >>= 4; /* max 32 segments */ if (mem->seg_align == 0) mem->seg_align = 1; mem->seg_base = ceil_int(mem->seg_base, mem->seg_align);#endif seg = list_entry(mem->seglist.next, struct memseg, list_head); seg->base = mem->seg_base; seg->wp = mem->seg_base; seg->end = mem->base + mem->size; }}int memmgr_placetask(struct taskent *te, struct coffobj *cobj, struct lkcmd *gbl_lkcmd){ struct section *scn; struct symbol *sym; section_for_each(scn, &cobj->scnlist) {#if 0 /* allow non-zero section address */ if (scn->vaddr != 0) { prmsg("section %s: " "attempted to place the section " "which has address value (0x%08lx)???\n", scn->name, scn->vaddr); break; }#endif /* * RAM model initialization * Do not allocate real memory to .cinit. */ if (!strcmp(scn->name, ".cinit")) { scn->flags |= COFF_STYP_COPY; continue; } /* search in task specific directive */ if (te->lkcmd && (placescn(te, scn, te->lkcmd, PLACE_MODE_EXACTNAME) != NULL)) goto place_done; /* search in global directive */ if (placescn(te, scn, gbl_lkcmd, PLACE_MODE_EXACTNAME) != NULL) goto place_done; /* * if section name contains ':' (ex. .text:aaa), * try with its basename. */ if (strchr(scn->name, ':')) { /* search in task specific directive */ if (te->lkcmd && (placescn(te, scn, te->lkcmd, PLACE_MODE_BASENAME) != NULL)) goto place_done; /* search in global directive */ if (placescn(te, scn, gbl_lkcmd, PLACE_MODE_BASENAME) != NULL) goto place_done; } /* place anywhere */ prmsg("section %s: could not find directive. ", scn->name); if (placescn(te, scn, NULL, PLACE_MODE_ANYWHERE) != NULL) goto place_done; prmsg("section %s: failed to place!\n", scn->name); return -1;place_done: /* update all symbol values in this section */ symbol_for_each(sym, &cobj->symlist) { if (sym->scn == scn) { sym->value += scn->vaddr - scn->vaddr_orig; } } } return 0;}static struct memmgr *placescn(struct taskent *te, struct section *scn, struct lkcmd *lkcmd, unsigned int mode){ struct directive *dir; struct memmgr *mem; struct list_head *dirlist; struct list_head *memlist; u32 align; if (place_mode_anywhere(mode)) { dir = &directive_default; mem = memmgr_default(); prmsg("placing it to default memory (%s).\n", mem->name); goto do_place; } /* can be null only when STICKY_LIST */ dirlist = lkcmd ? &lkcmd->dirlist : NULL; if (place_mode_basename(mode)) { /* * if this function called with basename mode, * the section name must contain ':'. */ char *tmpname; tmpname = strdup(scn->name); *strchr(tmpname, ':') = '\0'; dir = directive_find_by_scnnm(dirlist, tmpname); free(tmpname); } else dir = directive_find_by_scnnm(dirlist, scn->name); if (dir == NULL) return NULL; /* * FIXME: dir can have constant addr! */ if (dir->load.mem == NULL) { prmsg("section %s: " "could not get memory property for " "directive...\n", scn->name); return NULL; } /* can be null only when STICKY_LIST */ memlist = lkcmd ? &lkcmd->memlist : NULL; mem = memmgr_find_by_name(memlist, dir->load.mem);do_place: if ((align = dir->load.align) == 0) { /* use default align */ if (scn->flags & COFF_STYP_BSS) align = 4; /* bss section (XXX: Is this true?) */ else if (scn->flags & COFF_STYP_TEXT) align = 1; /* text section */ else#if 0 align = 2; /* data section */#else align = 4; /* data section // XXX: for secure ... Is it needed? */#endif } scn->vaddr = memmgr_malloc(mem, te, scn->size, align); if (scn->vaddr == DSPADDR_ILLEGAL) { prmsg("section %s: size = 0x%06x, align = 0x%x ... " "no space left in %s!\n", scn->name, scn->size, align, mem->name); return NULL; } return mem;}void memmgr_cleartask(struct taskent *te){ struct memmgr *mem; struct memseg *seg, *tmp; memmgr_for_each(mem, &g_memlist) { memseg_for_each_safe(seg, tmp, &mem->seglist) { if (seg->cobj == te->cobj) memmgr_freeseg(seg); } }}void memmgr_sendstat(struct list_head *list, int fd){ struct memmgr *mem; struct memseg *seg; char buf[256]; size_t strsz = 256 - SERVER_EVENT_HDRSZ; struct server_event *e = (struct server_event *)buf; int cnt; if (list == NULL) list = &g_memlist; e->event = DLD_EVENT_STRING; cnt = snprintf(e->data.s, strsz, "%-10s %-6s %-6s %-6s %-6s %-6s %-6s %-20s\n", "name", "base", "size", "sgbase", "sgbase", "segwp", "segend", "task"); e->len = SERVER_EVENT_HDRSZ + cnt; write(fd, e, e->len); memmgr_for_each(mem, list) { cnt = snprintf(e->data.s, strsz, "%-10s %06lx %06lx %06lx\n", mem->name, mem->base, mem->size, mem->seg_base); e->len = SERVER_EVENT_HDRSZ + cnt; write(fd, e, e->len); memseg_for_each(seg, &mem->seglist) { cnt = snprintf(e->data.s, strsz, "%10s %6s %6s %6s %06lx %06lx %06lx %-20s\n", "", "", "", "", seg->base, seg->wp, seg->end, seg->cobj ? seg->cobj->fn : "(none)"); e->len = SERVER_EVENT_HDRSZ + cnt; write(fd, e, e->len); } }}/* * debug stuff */void memmgr_printstat(struct list_head *list){ struct memmgr *mem; struct memseg *seg; if (list == NULL) list = &g_memlist; prmsg("memmgr list status...\n"); prmsg(" %-10s %-6s %-6s %-6s %-6s %-6s %-6s %-20s\n", "name", "base", "size", "sgbase", "sgbase", "segwp", "segend", "task"); memmgr_for_each(mem, list) { prmsg(" %-10s %06lx %06lx %06lx\n", mem->name, mem->base, mem->size, mem->seg_base); memseg_for_each(seg, &mem->seglist) { prmsg(" %10s %6s %6s %6s %06lx %06lx %06lx %-20s\n", "", "", "", "", seg->base, seg->wp, seg->end, seg->cobj ? seg->cobj->fn : "(none)"); } }}/* * memseg */static struct memseg *memseg_new(u32 base, u32 size){ struct memseg *seg = dld_malloc(sizeof(struct memseg), "memseg"); if (seg == NULL) return NULL; seg->base = base; seg->end = base + size; seg->wp = base; seg->cobj = NULL; return seg;}static void memseg_freelist(struct list_head *list){ struct memseg *seg, *tmp; memseg_for_each_safe(seg, tmp, list) { list_del(&seg->list_head); dld_free(seg, "memseg"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -