static void handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset) { int32_t oldseg; if (likely(!ofmt->herelabel)) return; if (unlikely(location.segment == NO_SEG)) return; oldseg = *segment; if (oldseg == location.segment && *offset == location.offset) { /* This label is defined at this location */ int32_t newseg; bool copyoffset = false; nasm_assert(lptr->defn.mangled); newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type, oldseg, &lptr->defn.subsection, ©offset); if (likely(newseg == oldseg)) return; *segment = newseg; if (copyoffset) { /* Maintain the offset from the old to the new segment */ switch_segment(newseg); location.offset = *offset; } else { /* Keep a separate offset for the new segment */ *offset = switch_segment(newseg); } } }
/* Same as saa_rnbytes, except position the counter first */ void saa_fread(struct SAA *s, size_t posn, void *data, size_t len) { size_t ix; nasm_assert(posn + len <= s->datalen); if (likely(s->blk_len == SAA_BLKLEN)) { ix = posn >> SAA_BLKSHIFT; s->rpos = posn & (SAA_BLKLEN - 1); } else {
void *saa_wstruct(struct SAA *s) { void *p; nasm_assert((s->wpos % s->elem_len) == 0); if (s->wpos + s->elem_len > s->blk_len) { nasm_assert(s->wpos == s->blk_len); if (s->wptr + s->elem_len > s->length) saa_extend(s); s->wblk++; s->wpos = 0; } p = *s->wblk + s->wpos; s->wpos += s->elem_len; s->wptr += s->elem_len; if (s->wptr > s->datalen) s->datalen = s->wptr; return p; }
void saa_rnbytes(struct SAA *s, void *data, size_t len) { char *d = data; nasm_assert(s->rptr + len <= s->datalen); while (len) { size_t l; const void *p; l = len; p = saa_rbytes(s, &l); memcpy(d, p, l); d += l; len -= l; } }
static void list_address(int32_t offset, const char *brackets, int64_t addr, int size) { char q[20]; char *r = q; nasm_assert(size <= 8); *r++ = brackets[0]; while (size--) { HEX(r, addr); addr >>= 8; r += 2; } *r++ = brackets[1]; *r = '\0'; list_out(offset, q); }
/* * Internal routine: finds the `union label' corresponding to the * given label name. Creates a new one, if it isn't found, and if * `create' is true. */ static union label *find_label(const char *label, bool create, bool *created) { union label *lptr, **lpp; char *label_str = NULL; struct hash_insert ip; nasm_assert(label != NULL); if (islocal(label)) label = label_str = nasm_strcat(prevlabel, label); lpp = (union label **) hash_find(<ab, label, &ip); lptr = lpp ? *lpp : NULL; if (lptr || !create) { if (created) *created = false; return lptr; } /* Create a new label... */ if (lfree->admin.movingon == END_BLOCK) { /* * must allocate a new block */ lfree->admin.next = nasm_malloc(LBLK_SIZE); lfree = lfree->admin.next; init_block(lfree); } if (created) *created = true; nasm_zero(*lfree); lfree->defn.label = perm_copy(label); lfree->defn.subsection = NO_SEG; if (label_str) nasm_free(label_str); hash_add(&ip, lfree->defn.label, lfree); return lfree++; }
void *saa_rstruct(struct SAA *s) { void *p; if (s->rptr + s->elem_len > s->datalen) return NULL; nasm_assert((s->rpos % s->elem_len) == 0); if (s->rpos + s->elem_len > s->blk_len) { s->rblk++; s->rpos = 0; } p = *s->rblk + s->rpos; s->rpos += s->elem_len; s->rptr += s->elem_len; return p; }
static char *perm_copy(const char *string) { char *p; int len = strlen(string)+1; nasm_assert(len <= PERMTS_SIZE); if (perm_tail->size - perm_tail->usage < len) { perm_tail->next = (struct permts *)nasm_malloc(sizeof(struct permts)); perm_tail = perm_tail->next; perm_tail->next = NULL; perm_tail->size = PERMTS_SIZE; perm_tail->usage = 0; } p = perm_tail->data + perm_tail->usage; memcpy(p, string, len); perm_tail->usage += len; return p; }