/************************************************************************* Copyright (c) 1984 by Nick de Smith This software is supplied for interest and non-profit making purposes only. Under no circumstance shall it be lent, copied or otherwise used for profit. All rights regarding the use and ownership of this software shall at all times remain with the author, who does not guarantee the accuracy or reliabilty of this software and who will not accept any liability for its use. This software may not be copied or distributed without the inclusion of the above copyright notice. January 31st 1984 *************************************************************************/ /************************************************************************* Program : CAM Module : PASS1.C Author : Nick de Smith November/December 1982 Description : First pass of the object module disassembler *************************************************************************/ #define MODULE #include #include "cam.h" /************************************************************************* * * * p a s s _ 1 * ----------- * * First pass through the object file. This pass reads the GSD and * extracts all psect definitions, all global references and all * absolute global definitions. * *************************************************************************/ global pass_1() { pass = 1; rewind(ip); rec_num = 0; b_init(); eom = egsd = FALSE; dbg("Started PASS_1\n"); while (!eom && !egsd) { read_record(b_current); proc_1(); }; if (eom) bug("End of GSD not before EOM"); dbg("Ended PASS_1\n"); } /************************************************************************* * * * p r o c _ 1 * ----------- * * Process a pass one object record. We only examine GSD type * entries. In a valid object file, there should be a EGSD entry * before the EOM. If this is not the case the object file is * corrupt/invalid format. * *************************************************************************/ local proc_1() { register int type; switch (type = next_word(b_current)) { case T_GSD: gsd_1(); break; case T_EGSD: egsd = TRUE; dbg("End of GSD\n"); break; case T_TEXT: case T_RELD: case T_ISD: break; case T_EOM: eom = TRUE; break; default: bug("Bad object record, type = %06o", type); } } /************************************************************************* * * * g s d _ 1 * --------- * * Process a pass one GSD record. * *************************************************************************/ local gsd_1() { register int flags, _entry, value; int temp; int i[2]; while (b_current->b_left) { i[0] = next_word(b_current); i[1] = next_word(b_current); flags = next_byte(b_current); _entry = next_byte(b_current); value = next_word(b_current); switch (_entry) { case T_MODN: modnam[0] = i[0]; modnam[1] = i[1]; break; case T_CSECT: /* Magic nos below are .rad50 ". ABS." */ if (i[0] == 0127401 && i[1] == 0007624) flags = P_GBL | P_OVR; else if (*i) /* Named .csect */ flags = P_GBL | P_REL | P_OVR; else /* Blank .csect */ flags = P_REL; p_new(i, value, flags); break; case T_ISN: insert(seg_cur, value, i, S_STRONG); break; case T_TADDR: if (!((t_addr.s_flags = segtbl[temp = find(i)].p_flags) & P_REL) && value == 1) break; t_addr.s_flags |= S_VALID; t_addr.s_name[0] = temp; t_addr.s_offset = value; insert(temp, value, i, S_WEAK | S_CREF | S_EXT); break; case T_GSN: if (!(flags & G_DEF)) { insert(seg_cur, 0, i, S_GREF); break; } if (!(flags & G_REL)) { abs_f = TRUE; if (!sort_g) insert(seg_cur, value, i, S_STRONG | S_GLOBAL | S_GABS); } insert(seg_cur, value, i, S_GLOBAL | S_STRONG); break; case T_PSECT: p_new(i, value, flags); break; case T_IDENT: ident_f = TRUE; _ident[0] = i[0]; _ident[1] = i[1]; break; case T_MARR: warn("Mapped array definition ignored\n"); break; case T_COMP: warn("Completion routine address ignored\n"); break; default: bug("Unknown GSD entry, type = %06o", _entry); } } } /************************************************************************* * * * p _ n e w * --------- * * Add a new .psect name to the list. * *************************************************************************/ local p_new(name, length, flags) int name[]; int length, flags; { if (seg_max >= MAX_SEG) bug("Psect table overflow"); seg_ptr = &segtbl[seg_cur = ++seg_max]; seg_ptr->p_flags = flags; seg_ptr->p_name[0] = name[0]; seg_ptr->p_name[1] = name[1]; seg_ptr->p_mlength = length; seg_ptr->p_dot = 0; seg_ptr->p_symb = NULL; }