gd_addr *gd_load(mstr *v) { void *file_ptr; /* This is a temporary structure as the file open and manipulations are currently stubs */ header_struct *header, temp_head; gd_addr *table, *gd_addr_ptr; gd_binding *map, *map_top; gd_region *reg, *reg_top; uint4 t_offset, size; short i; error_def(ERR_GDINVALID); file_ptr = open_gd_file(v); for (gd_addr_ptr = gd_addr_head; gd_addr_ptr; gd_addr_ptr = gd_addr_ptr->link) { /* if already open then return old structure */ if (comp_gd_addr(gd_addr_ptr, file_ptr)) { close_gd_file(file_ptr); return gd_addr_ptr; } } file_read(file_ptr, sizeof(header_struct), (uchar_ptr_t)&temp_head, 1); /* Read in header and verify is valid GD */ for (i = 0; i < GDE_LABEL_NUM; i++) { if (!memcmp(temp_head.label, gde_labels[i], GDE_LABEL_SIZE - 1)) break; } if (GDE_LABEL_NUM == i) { close_gd_file(file_ptr); rts_error(VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL), sizeof(temp_head.label), temp_head.label); } size = LEGAL_IO_SIZE(temp_head.filesize); header = (header_struct *)malloc(size); file_read(file_ptr, size, (uchar_ptr_t)header, 1); /* Read in body of file */ table = (gd_addr *)((char *)header + sizeof(header_struct)); table->local_locks = (struct gd_region_struct *)((UINTPTR_T)table->local_locks + (UINTPTR_T)table); table->maps = (struct gd_binding_struct *)((UINTPTR_T)table->maps + (UINTPTR_T)table); table->regions = (struct gd_region_struct *)((UINTPTR_T)table->regions + (UINTPTR_T)table); table->segments = (struct gd_segment_struct *)((UINTPTR_T)table->segments + (UINTPTR_T)table); table->end = (table->end + (UINTPTR_T)table); for (map = table->maps, map_top = map + table->n_maps; map < map_top; map++) { t_offset = map->reg.offset; map->reg.addr = (gd_region *)((char *)table + t_offset); } for (reg = table->regions, reg_top = reg + table->n_regions; reg < reg_top; reg++) { t_offset = reg->dyn.offset; reg->dyn.addr = (gd_segment *)((char *)table + t_offset); } table->link = gd_addr_head; gd_addr_head = table; fill_gd_addr_id(gd_addr_head, file_ptr); close_gd_file(file_ptr); table->tab_ptr = (hash_table_mname *)malloc(sizeof(hash_table_mname)); init_hashtab_mname(table->tab_ptr, 0); return table; }
/*+ Function: GD_LOAD Syntax: gd_addr *gd_load(mstr *gd_name) Open a global directory file and verify that it is a valid GD. Determine if it has already been opened. If not, setup and initialize the GT.M structures used to access the GD based on the information in the file, enter in the linked list of global directories and return a pointer to it. If already opened, return a pointer to it. Prototype: ? Return: gd_addr * (all errors are signalled) Arguments: gd_name is the name of the file to be opened Side Effects: None Notes: A) While checking may be done earlier for duplicate names, unique identification of files can require OS specific operations useable only after the file is open, so checks must be done within this function for duplicate files. -*/ gd_addr *gd_load(mstr *v) { void *file_ptr; /* is a temporary structure as the file open and manipulations are currently stubs */ header_struct *header, temp_head, disp_head; gd_addr *table, *gd_addr_ptr; gd_binding *map, *map_top; gd_region *reg, *reg_top; uint4 t_offset, size; gd_gblname *gnam, *gnam_top; int i, n_regions, arraysize, disp_len; trans_num *array; # ifdef DEBUG boolean_t prevMapIsSpanning, currMapIsSpanning, gdHasSpanGbls; boolean_t isSpannedReg[256]; /* currently we allow for a max of 256 regions in this dbg code */ # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; file_ptr = open_gd_file(v); for (gd_addr_ptr = gd_addr_head; gd_addr_ptr; gd_addr_ptr = gd_addr_ptr->link) { /* if already open then return old structure */ if (comp_gd_addr(gd_addr_ptr, file_ptr)) { close_gd_file(file_ptr); return gd_addr_ptr; } } file_read(file_ptr, SIZEOF(header_struct), (uchar_ptr_t)&temp_head, 1); /* Read in header and verify is valid GD */ for (i = 0; i < GDE_LABEL_NUM; i++) { if (!memcmp(temp_head.label, gde_labels[i], GDE_LABEL_SIZE - 1)) break; } if (GDE_LABEL_NUM == i) { close_gd_file(file_ptr); disp_len = SIZEOF(disp_head.label); format2disp(temp_head.label, SIZEOF(temp_head.label), disp_head.label, &disp_len); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL), disp_len, disp_head.label); } size = LEGAL_IO_SIZE(temp_head.filesize); header = (header_struct *)malloc(size); file_read(file_ptr, size, (uchar_ptr_t)header, 1); /* Read in body of file */ table = (gd_addr *)((char *)header + SIZEOF(header_struct)); table->local_locks = (struct gd_region_struct *)((UINTPTR_T)table->local_locks + (UINTPTR_T)table); assert(table->var_maps_len == ((UINTPTR_T)table->regions - (UINTPTR_T)table->maps) - (table->n_maps * SIZEOF(gd_binding))); table->maps = (struct gd_binding_struct *)((UINTPTR_T)table->maps + (UINTPTR_T)table); table->regions = (struct gd_region_struct *)((UINTPTR_T)table->regions + (UINTPTR_T)table); table->segments = (struct gd_segment_struct *)((UINTPTR_T)table->segments + (UINTPTR_T)table); table->gblnames = (struct gd_gblname_struct *)((UINTPTR_T)table->gblnames + (UINTPTR_T)table); table->end = (table->end + (UINTPTR_T)table); n_regions = table->n_regions; for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++) { t_offset = reg->dyn.offset; reg->dyn.addr = (gd_segment *)((char *)table + t_offset); # ifdef DEBUG assert((reg - table->regions) < ARRAYSIZE(isSpannedReg)); isSpannedReg[reg - table->regions] = FALSE; # endif } # ifdef DEBUG prevMapIsSpanning = FALSE; currMapIsSpanning = FALSE; gdHasSpanGbls = FALSE; # endif for (map = table->maps, map_top = map + table->n_maps; map < map_top; map++) { t_offset = map->reg.offset; map->reg.addr = (gd_region *)((char *)table + t_offset); # ifdef DEBUG currMapIsSpanning = ((map->gvname_len + 1) != map->gvkey_len); if (currMapIsSpanning) gdHasSpanGbls = TRUE; if (currMapIsSpanning || prevMapIsSpanning) isSpannedReg[map->reg.addr - table->regions] = TRUE; prevMapIsSpanning = currMapIsSpanning; # endif t_offset = map->gvkey.offset; map->gvkey.addr = (char *)table + t_offset; assert('\0' == map->gvkey.addr[map->gvname_len]); assert('\0' == map->gvkey.addr[map->gvkey_len]); assert('\0' == map->gvkey.addr[map->gvkey_len - 1]); assert((map->gvname_len + 1) <= map->gvkey_len); } # ifdef DEBUG assert(table->has_span_gbls == gdHasSpanGbls); for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++) assert(reg->is_spanned == isSpannedReg[reg - table->regions]); for (gnam = table->gblnames, gnam_top = gnam + table->n_gblnames; gnam < gnam_top; gnam++) { assert(SIZEOF(gnam->gblname) == (MAX_MIDENT_LEN + 1)); assert('\0' == gnam->gblname[MAX_MIDENT_LEN]); } # endif table->link = gd_addr_head; gd_addr_head = table; fill_gd_addr_id(gd_addr_head, file_ptr); close_gd_file(file_ptr); table->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(table->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); if (table->has_span_gbls && (TREF(gd_targ_reg_array_size) < n_regions)) { array = TREF(gd_targ_reg_array); if (NULL != array) free(array); arraysize = n_regions * SIZEOF(*array); array = malloc(arraysize); memset(array, 0, arraysize); TREF(gd_targ_reg_array) = array; TREF(gd_targ_reg_array_size) = arraysize; } return table; }