dsk_err_t remote_creat(DSK_DRIVER *self, const char *filename) { RPCFUNC function; char *outname, *outtype, *outcomp, *comment; dsk_err_t err = remote_lookup(self, filename, &outname, &outtype, &outcomp); if (err) return err; function = self->dr_remote->rd_class->rc_call; err = dsk_r_creat(self, function, &self->dr_remote->rd_handle, outname, outtype, outcomp); dsk_free(outname); if (err) return err; err = dsk_r_properties(self, function, self->dr_remote->rd_handle); if (err) return err; /* if (implements(self, RPC_DSK_GETCOMMENT)) { */ err = dsk_r_get_comment(self, function, self->dr_remote->rd_handle, &comment); if (err) return err; if (comment != NULL) err = dsk_set_comment(self, comment); /* } */ return err; }
PROTECTED int unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg) { unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp; const struct ia64_table_entry *e = NULL; unw_word_t handler_offset, segbase = 0; struct ia64_table_entry ent; int ret, is_local; assert ((di->format == UNW_INFO_FORMAT_TABLE || di->format == UNW_INFO_FORMAT_REMOTE_TABLE) && (ip >= di->start_ip && ip < di->end_ip)); pi->flags = 0; pi->unwind_info = 0; pi->handler = 0; if (likely (di->format == UNW_INFO_FORMAT_TABLE)) { segbase = di->u.ti.segbase; e = lookup ((struct ia64_table_entry *) di->u.ti.table_data, di->u.ti.table_len * sizeof (unw_word_t), ip - segbase); } #ifndef UNW_LOCAL_ONLY else { segbase = di->u.rti.segbase; if ((ret = remote_lookup (as, di->u.rti.table_data, di->u.rti.table_len * sizeof (unw_word_t), ip - segbase, &ent, arg)) < 0) return ret; if (ret) e = &ent; } #endif if (!e) { /* IP is inside this table's range, but there is no explicit unwind info => use default conventions (i.e., this is NOT an error). */ memset (pi, 0, sizeof (*pi)); pi->start_ip = 0; pi->end_ip = 0; pi->gp = di->gp; pi->lsda = 0; return 0; } pi->start_ip = e->start_offset + segbase; pi->end_ip = e->end_offset + segbase; hdr_addr = e->info_offset + segbase; info_addr = hdr_addr + 8; /* Read the header word. Note: the actual unwind-info is always assumed to reside in memory, independent of whether di->format is UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */ if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) return ret; if (IA64_UNW_VER (hdr) != 1) { Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n", IA64_UNW_VER (hdr), (unsigned long) hdr, (unsigned long) hdr_addr); return -UNW_EBADVERSION; } info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr); is_local = is_local_addr_space (as); /* If we must have the unwind-info, return it. Also, if we are in the local address-space, return the unwind-info because it's so cheap to do so and it may come in handy later on. */ if (need_unwind_info || is_local) { pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr); if (is_local) pi->unwind_info = (void *) (uintptr_t) info_addr; else { /* Internalize unwind info. Note: since we're doing this only for non-local address spaces, there is no signal-safety issue and it is OK to use malloc()/free(). */ pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr)); if (!pi->unwind_info) return -UNW_ENOMEM; wp = (unw_word_t *) pi->unwind_info; for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp) { if ((ret = read_mem (as, addr, wp, arg)) < 0) { free (pi->unwind_info); return ret; } } } } if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) { /* read the personality routine address (address is gp-relative): */ if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0) return ret; Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp); if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0) return ret; } pi->lsda = info_end_addr + 8; pi->gp = di->gp; pi->format = di->format; return 0; }