/*------------------------------------------------------------------------- * Function: _lite_PD_rl_pdb * * Purpose: Release the storage associated with the PDBfile * * Return: void * * Programmer: Adapted from PACT PDB * Mar 5, 1996 12:03 PM EST * * Modifications: * Eric Brugger, Mon Dec 7 10:51:58 PST 1998 * Removed call to lite_PD_reset_ptr_list since it was removed. I * added a call to free current_prefix to close a memory leak. * *------------------------------------------------------------------------- */ void _lite_PD_rl_pdb (PDBfile *file) { SFREE(file->date); _lite_PD_rl_standard(file->std); _lite_PD_rl_standard(file->host_std); _lite_PD_rl_alignment(file->align); _lite_PD_rl_alignment(file->host_align); if (file->attrtab != NULL) _lite_PD_clr_table(file->attrtab, NULL); _lite_PD_clr_table(file->host_chart,(FreeFuncType)_lite_PD_rl_defstr); _lite_PD_clr_table(file->chart,(FreeFuncType)_lite_PD_rl_defstr); _lite_PD_clr_table(file->symtab,(FreeFuncType)_lite_PD_rl_syment_d); if (file->previous_file != NULL) SFREE(file->previous_file); if (file->current_prefix != NULL) SFREE(file->current_prefix); if (file->type != NULL) SFREE(file->type); if (lite_LAST != NULL) SFREE(lite_LAST); if (lite_PD_DEFSTR_S != NULL) SFREE(lite_PD_DEFSTR_S); lite_PD_DEFSTR_S = NULL; if (lite_PD_SYMENT_S != NULL) SFREE(lite_PD_SYMENT_S); lite_PD_SYMENT_S = NULL; if (lite_io_close_hook == (PFfclose) _lite_PD_pio_close) lite_io_close_hook = (PFfclose) fclose; if (lite_io_seek_hook == (PFfseek) _lite_PD_pio_seek) lite_io_seek_hook = (PFfseek) fseek; if (lite_io_printf_hook == (PFfprintf) _lite_PD_pio_printf) lite_io_printf_hook = (PFfprintf) fprintf; SFREE(file->name); SFREE(file); }
/*------------------------------------------------------------------------- * Function: lite_PD_open * * Purpose: Open an existing PDB file, extract the symbol table and * structure chart. * * Return: Success: Ptr to the PDB file structure * * Failure: NULL * * Programmer: Adapted from the PACT PDB library * Mar 4, 1996 10:26 AM EST * * Modifications: * * Robb Matzke, 4 Mar 1996 * Fixed indentation. Files can only be opened with mode `r'. * * Robb Matzke, 17 Apr 1996 * Added write capability back into the function, but it is protected * with #ifdef PDB_WRITE. * * Mark C. Miller, Fri Apr 13 22:37:56 PDT 2012 * Changed mode string checks to strchr to accomodate wider variety * of mode characters for new hash table size and open modes. * * Mark C. Miller, Thu Jun 14 13:25:02 PDT 2012 * Remove call to io_close in ABORT case. The file pointer may not * have been properly initialized. *------------------------------------------------------------------------- */ PDBfile * lite_PD_open (char *name, char *mode) { char str[MAXLINE], *token; PDBfile *file=NULL; static FILE *fp; syment *ep; #ifdef PDB_WRITE /* * If opened in write mode use PD_CREATE instead. */ if (strchr(mode,'w')) return lite_PD_create (name); #else assert (!strchr(mode,'r')) ; #endif switch (setjmp(_lite_PD_open_err)) { case ABORT: if (fp) io_close(fp); return(NULL); case ERR_FREE: return(file); default: memset(lite_PD_err, 0, MAXLINE); break; } /* * Open the file */ strcpy(str, name); #ifdef PDB_WRITE fp = io_open(str, BINARY_MODE_RPLUS); if (fp == NULL) { if (strchr(mode,'r')) { #endif fp = io_open(str, BINARY_MODE_R); if (fp == NULL) { lite_PD_error("CAN'T OPEN FILE IN READ-ONLY MODE - PD_OPEN", PD_OPEN); } #ifdef PDB_WRITE } else if (strchr(mode,'a')) { return lite_PD_create (name); } else { lite_PD_error("CAN'T OPEN FILE - PD_OPEN", PD_OPEN); } } #endif if (lite_PD_buffer_size != -1) { if (io_setvbuf(fp, NULL, _IOFBF, (size_t) lite_PD_buffer_size)) { lite_PD_error("CAN'T SET FILE BUFFER - PD_OPEN", PD_OPEN); } } file = _lite_PD_mk_pdb(str, mode); if (file == NULL) { lite_PD_error("CAN'T ALLOCATE PDBFILE - PD_OPEN", PD_OPEN); } file->stream = fp; #ifdef PDB_WRITE if (strchr(mode,'a')) file->mode = PD_APPEND; else file->mode = PD_OPEN; #else file->mode = PD_OPEN ; #endif /* * Attempt to read an ASCII header. */ if (io_seek(fp, 0L, SEEK_SET)) { _lite_PD_rl_pdb(file); lite_PD_error("FSEEK FAILED TO FIND ORIGIN - PD_OPEN", PD_OPEN); } if (_lite_PD_rfgets(str, MAXLINE, fp) == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T READ THE FILE HEADER - PD_OPEN", PD_OPEN); } /* * The first token should be the identifying header token. */ token = strtok(str, " "); if (token == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("FILE HEADER NOT ASCII - PD_OPEN", PD_OPEN); } if (strcmp(token, HeadTok) == 0) { /* * This is a PDB_SYSTEM_VERSION 2 or later file. * Read the primitive data type formats which set the standard. */ if (!_lite_PD_rd_format(file)) { _lite_PD_rl_pdb(file); lite_PD_error("FAILED TO READ FORMATS - PD_OPEN", PD_OPEN); } } else if (strcmp(token, OldHeadTok) == 0) { /* * This is a pre-PDB_SYSTEM_VERSION 2 style file. The second token * is the machine type that wrote the file. Set the file->std for * machine type for PD_open the file->std is always the PDBfile standard. * Alignment issues are not properly handled before PDB_SYSTEM_VERSION 3 * but do the best that we can. */ token = strtok(NULL, " "); if (token == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("INCOMPLETE HEADER - PD_OPEN", PD_OPEN); } switch (atoi(token)) { case IEEE_32_64: file->std = _lite_PD_copy_standard(&lite_IEEEA_STD); file->align = _lite_PD_copy_alignment(&lite_M68000_ALIGNMENT); break; case IEEE_32_96: file->std = _lite_PD_copy_standard(&lite_IEEEB_STD); file->align = _lite_PD_copy_alignment(&lite_M68000_ALIGNMENT); break; case INTEL_X86: file->std = _lite_PD_copy_standard(&lite_INTELA_STD); file->align = _lite_PD_copy_alignment(&lite_INTELA_ALIGNMENT); break; case CRAY_64: file->std = _lite_PD_copy_standard(&lite_CRAY_STD); file->align = _lite_PD_copy_alignment(&lite_UNICOS_ALIGNMENT); break; case VAX_11: file->std = _lite_PD_copy_standard(&lite_VAX_STD); file->align = _lite_PD_copy_alignment(&lite_DEF_ALIGNMENT); break; default: file->std = _lite_PD_copy_standard(&lite_DEF_STD); file->align = _lite_PD_copy_alignment(&lite_DEF_ALIGNMENT); break; } /* * To correctly handle the situation in which many PDBfiles are open * at the same time always try to latch on to the file->host_std. * Alignment issues are not properly handled before PDB_SYSTEM_VERSION 3 * but do the best that we can */ if (_lite_PD_compare_std(file->host_std, file->std, file->host_align, file->align)) { _lite_PD_rl_standard(file->std); file->std = _lite_PD_copy_standard(file->host_std); _lite_PD_rl_alignment(file->align); file->align = _lite_PD_copy_alignment(file->host_align); } } else { _lite_PD_rl_pdb(file); lite_PD_error("BAD FILE HEADER - PD_OPEN", PD_OPEN); } /* * Record the current file position as the location of the symbol table * address and sequentially the chart address. */ file->headaddr = io_tell(fp); if (file->headaddr == -1L) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T FIND HEADER ADDRESS - PD_OPEN", PD_OPEN); } /* * Read the address of the symbol table and structure chart. */ if (_lite_PD_rfgets(str, MAXLINE, fp) == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T READ SYMBOL TABLE ADDRESS - PD_OPEN", PD_OPEN); } token = strtok(str, "\001"); if (token == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("BAD STRUCTURE CHART ADDRESS - PD_OPEN", PD_OPEN); } file->chrtaddr = atol(token); token = strtok(NULL, "\001"); if (token == NULL) { _lite_PD_rl_pdb(file); lite_PD_error("BAD SYMBOL TABLE ADDRESS - PD_OPEN", PD_OPEN); } file->symtaddr = atol(token); /* * Read the symbol table first so that the file pointer is positioned * to the "extra" information, then read the "extra's" to get the * alignment data, and finish with the structure chart which needs * the alignment data */ /* * Read the symbol table. */ if (io_seek(fp, file->symtaddr, SEEK_SET)) { _lite_PD_rl_pdb(file); lite_PD_error("FSEEK FAILED SYMBOL TABLE - PD_OPEN", PD_OPEN); } if (!_lite_PD_rd_symt(file)) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T READ SYMBOL TABLE - PD_OPEN", PD_OPEN); } /* * Read the miscellaneous data. */ if (!_lite_PD_rd_extras(file)) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T READ MISCELLANEOUS DATA - PD_OPEN", PD_OPEN); } /* * Initialize the pdb system defs and structure chart. */ _lite_PD_init_chrt(file); /* * Read the structure chart. */ if (io_seek(fp, file->chrtaddr, SEEK_SET)) { _lite_PD_rl_pdb(file); lite_PD_error("FSEEK FAILED STRUCTURE CHART - PD_OPEN", PD_OPEN); } if (!_lite_PD_rd_chrt(file)) { _lite_PD_rl_pdb(file); lite_PD_error("CAN'T READ STRUCTURE CHART - PD_OPEN", PD_OPEN); } ep = lite_PD_inquire_entry(file, PDB_ATTRIBUTE_TABLE, TRUE, NULL); if (ep != NULL) { if (!lite_PD_read(file, PDB_ATTRIBUTE_TABLE, &file->attrtab)) { lite_PD_close(file); lite_PD_error("FAILED TO READ ATTRIBUTE TABLE - PD_OPEN", PD_OPEN); } _lite_PD_convert_attrtab(file); file->chrtaddr = PD_entry_address(ep); _lite_PD_rl_syment(ep); lite_SC_hash_rem(_lite_PD_fixname(file, PDB_ATTRIBUTE_TABLE), file->symtab); } else { file->attrtab = NULL; } /* * Position the file pointer to the location of the structure chart. */ if (io_seek(fp, file->chrtaddr, SEEK_SET)) { lite_PD_close(file); lite_PD_error("FSEEK FAILED CHART - PD_OPEN", PD_OPEN); } return(file); }
PDBfile * lite_PD_create (char *name) { char str[MAXLINE]; PDBfile *file; static FILE *fp; file = NULL; switch (setjmp(_lite_PD_create_err)) { case ABORT: if (fp) io_close(fp); return(NULL); case ERR_FREE: return(file); default: memset(lite_PD_err, 0, MAXLINE); break; } /* * Open the file. */ strncpy(str, name, sizeof(str)); str[sizeof(str)-1] = '\0'; fp = io_open(str, BINARY_MODE_WPLUS); if (!fp) lite_PD_error("CAN'T CREATE FILE - PD_CREATE", PD_CREATE); if (lite_PD_buffer_size != -1) { if (io_setvbuf(fp, NULL, _IOFBF, (size_t) lite_PD_buffer_size)) { lite_PD_error("CAN'T SET FILE BUFFER - PD_CREATE", PD_OPEN); } } /* * Make the PDBfile. */ file = _lite_PD_mk_pdb(str, lite_PD_DEF_CREATM); if (file == NULL) { lite_PD_error("CAN'T ALLOCATE PDBFILE - PD_CREATE", PD_OPEN); } file->stream = fp; file->mode = PD_CREATE; /* * Set the file data conversion standard - and yes someone might pick * a target standard which is the current standard */ file->std = _lite_PD_copy_standard(file->host_std); file->align = _lite_PD_copy_alignment(file->host_align); if (lite_REQ_STANDARD != NULL) { if (!_lite_PD_compare_std(lite_REQ_STANDARD, file->std, lite_REQ_ALIGNMENT, file->align)) { _lite_PD_rl_standard(file->std); file->std = _lite_PD_copy_standard(lite_REQ_STANDARD); _lite_PD_rl_alignment(file->align); file->align = _lite_PD_copy_alignment(lite_REQ_ALIGNMENT); } lite_REQ_STANDARD = NULL; } /* * Write the ASCII header. */ io_printf(fp, "%s\n", HeadTok); if (io_flush(fp)) { lite_PD_error("FFLUSH FAILED BEFORE HEADER - PD_CREATE", PD_CREATE); } /* * Write the primitive data type formats. */ if (!_lite_PD_wr_format(file)) { lite_PD_error("FAILED TO WRITE FORMATS - PD_CREATE", PD_CREATE); } /* * Record the current file position as the location of the symbol table * address and sequentially the chart address */ if ((file->headaddr = io_tell(fp)) == -1L) { lite_PD_error("CAN'T FIND HEADER ADDRESS - PD_CREATE", PD_CREATE); } /* * Initialize the pdb system defs and structure chart. */ _lite_PD_init_chrt(file); if (io_flush(fp)) { lite_PD_error("FFLUSH FAILED AFTER HEADER - PD_CREATE", PD_CREATE); } memset(str, 0, PAD_SIZE); if (io_write(str, (size_t) 1, PAD_SIZE, fp) != PAD_SIZE) { lite_PD_error("FAILED TO PAD FILE FOR MPW - PD_CREATE", PD_CREATE); } file->chrtaddr = file->headaddr + 128L; if (io_seek(fp, file->chrtaddr, SEEK_SET)) { lite_PD_error("FAILED TO FIND START OF DATA - PD_CREATE", PD_CREATE); } file->system_version = PDB_SYSTEM_VERSION; file->date = lite_SC_date(); return(file); }