Newsgroups: comp.sources.unix From: bruce@beta.cs.su.oz.au (Bruce Janson) Subject: v25i158: trash - simulate process execution in MIPS RISC/os 4.52, Part04/08 Sender: unix-sources-moderator@pa.dec.com Approved: vixie@pa.dec.com Submitted-By: bruce@beta.cs.su.oz.au (Bruce Janson) Posting-Number: Volume 25, Issue 158 Archive-Name: trash/part04 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'optab.c' <<'END_OF_FILE' X#include "diblock.h" X#include "instrn.h" X Xextern dinstrn *i_absfmt(); Xextern dinstrn *i_add(); Xextern dinstrn *i_addfmt(); Xextern dinstrn *i_addi(); Xextern dinstrn *i_addiu(); Xextern dinstrn *i_addu(); Xextern dinstrn *i_and(); Xextern dinstrn *i_andi(); Xextern dinstrn *i_bc1f(); Xextern dinstrn *i_bc1t(); Xextern dinstrn *i_beq(); Xextern dinstrn *i_bgez(); Xextern dinstrn *i_bgtz(); Xextern dinstrn *i_blez(); Xextern dinstrn *i_bltz(); Xextern dinstrn *i_bne(); Xextern dinstrn *i_ceq(); Xextern dinstrn *i_cfc1(); Xextern dinstrn *i_cle(); Xextern dinstrn *i_clt(); Xextern dinstrn *i_cole(); Xextern dinstrn *i_colt(); Xextern dinstrn *i_ctc1(); Xextern dinstrn *i_cule(); Xextern dinstrn *i_cult(); Xextern dinstrn *i_cvtd(); Xextern dinstrn *i_cvts(); Xextern dinstrn *i_cvtw(); Xextern dinstrn *i_div(); Xextern dinstrn *i_divfmt(); Xextern dinstrn *i_divu(); Xextern dinstrn *i_j(); Xextern dinstrn *i_jal(); Xextern dinstrn *i_jalr(); Xextern dinstrn *i_jr(); Xextern dinstrn *i_lb(); Xextern dinstrn *i_lbu(); Xextern dinstrn *i_lh(); Xextern dinstrn *i_lhu(); Xextern dinstrn *i_lui(); Xextern dinstrn *i_lw(); Xextern dinstrn *i_lwc1(); Xextern dinstrn *i_lwl(); Xextern dinstrn *i_lwr(); Xextern dinstrn *i_mfc1(); Xextern dinstrn *i_mfhi(); Xextern dinstrn *i_mflo(); Xextern dinstrn *i_mtc1(); Xextern dinstrn *i_mthi(); Xextern dinstrn *i_mtlo(); Xextern dinstrn *i_mulfmt(); Xextern dinstrn *i_mult(); Xextern dinstrn *i_multu(); Xextern dinstrn *i_movfmt(); Xextern dinstrn *i_negfmt(); Xextern dinstrn *i_nor(); Xextern dinstrn *i_or(); Xextern dinstrn *i_ori(); Xextern dinstrn *i_sb(); Xextern dinstrn *i_sh(); Xextern dinstrn *i_sll(); Xextern dinstrn *i_sllv(); Xextern dinstrn *i_slt(); Xextern dinstrn *i_slti(); Xextern dinstrn *i_sltiu(); Xextern dinstrn *i_sltu(); Xextern dinstrn *i_sra(); Xextern dinstrn *i_srav(); Xextern dinstrn *i_srl(); Xextern dinstrn *i_srlv(); Xextern dinstrn *i_sub(); Xextern dinstrn *i_subfmt(); Xextern dinstrn *i_subu(); Xextern dinstrn *i_sw(); Xextern dinstrn *i_swc1(); Xextern dinstrn *i_swl(); Xextern dinstrn *i_swr(); Xextern dinstrn *i_syscall(); Xextern dinstrn *i_undef(); Xextern dinstrn *i_xor(); Xextern dinstrn *i_xori(); X X/* X * The primary opcode instruction table. X */ Xinstrn optab[] = X{ X OP("special", IF_R, i_undef, "????"), X OP("bcond", IF_I, i_undef, "????"), X OP("j", IF_J, i_j, "a-31"), X OP("jal", IF_J, i_jal, "a-32"), X OP("beq", IF_I, i_beq, "a-17"), X OP("bne", IF_I, i_bne, "a-24"), X OP("blez", IF_I, i_blez, "a-21"), X OP("bgtz", IF_I, i_bgtz, "a-20"), X X OP("addi", IF_I, i_addi, "a-10"), X OP("addiu", IF_I, i_addiu, "a-11"), X OP("slti", IF_I, i_slti, "a-65"), X OP("sltiu", IF_I, i_sltiu, "a-66"), X OP("andi", IF_I, i_andi, "a-14"), X OP("ori", IF_I, i_ori, "a-58"), X OP("xori", IF_I, i_xori, "a-86"), X OP("lui", IF_I, i_lui, "a-39"), X X OP("cop0", IF_R, i_undef, "a-27"), X OP("cop1", IF_U, i_undef, "a-27"), X OP("cop2", IF_U, i_undef, "a-27"), X OP("cop3", IF_U, i_undef, "a-27"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("lb", IF_I, i_lb, "a-35"), X OP("lh", IF_I, i_lh, "a-37"), X OP("lwl", IF_I, i_lwl, "a-42"), X OP("lw", IF_I, i_lw, "a-40"), X OP("lbu", IF_I, i_lbu, "a-36"), X OP("lhu", IF_I, i_lhu, "a-38"), X OP("lwr", IF_I, i_lwr, "a-44"), X OP("", IF_U, i_undef, "????"), X X OP("sb", IF_I, i_sb, "a-60"), X OP("sh", IF_I, i_sh, "a-61"), X OP("swl", IF_I, i_swl, "a-76"), X OP("sw", IF_I, i_sw, "a-74"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("swr", IF_I, i_swr, "a-78"), X OP("", IF_U, i_undef, "????"), X X OP("lwc0", IF_U, i_undef, "a-41"), X OP("lwc1", IF_I, i_lwc1, "b-20"), X OP("lwc2", IF_U, i_undef, "a-41"), X OP("lwc3", IF_U, i_undef, "a-41"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("swc0", IF_U, i_undef, "a-75"), X OP("swc1", IF_I, i_swc1, "b-27"), X OP("swc2", IF_U, i_undef, "a-75"), X OP("swc3", IF_U, i_undef, "a-75"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X}; X X/* X * The special opcode instruction table. X */ Xinstrn optab_special[] = X{ X OP("sll", IF_R, i_sll, "a-62"), X OP("", IF_U, i_undef, "????"), X OP("srl", IF_R, i_srl, "a-70"), X OP("sra", IF_R, i_sra, "a-68"), X OP("sllv", IF_R, i_sllv, "a-63"), X OP("", IF_U, i_undef, "????"), X OP("srlv", IF_R, i_srlv, "a-71"), X OP("srav", IF_R, i_srav, "a-69"), X X OP("jr", IF_R, i_jr, "a-34"), X OP("jalr", IF_R, i_jalr, "a-33"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("syscall", IF_R, i_syscall, "a-80"), X OP("break", IF_U, i_undef, "a-25"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("mfhi", IF_R, i_mfhi, "a-48"), X OP("mthi", IF_R, i_mthi, "a-52"), X OP("mflo", IF_R, i_mflo, "a-49"), X OP("mtlo", IF_R, i_mtlo, "a-53"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("mult", IF_R, i_mult, "a-54"), X OP("multu", IF_R, i_multu, "a-55"), X OP("div", IF_R, i_div, "a-29"), X OP("divu", IF_R, i_divu, "a-30"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("add", IF_R, i_add, "a-09"), X OP("addu", IF_R, i_addu, "a-12"), X OP("sub", IF_R, i_sub, "a-72"), X OP("subu", IF_R, i_subu, "a-73"), X OP("and", IF_R, i_and, "a-13"), X OP("or", IF_R, i_or, "a-57"), X OP("xor", IF_R, i_xor, "a-85"), X OP("nor", IF_R, i_nor, "a-56"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("slt", IF_R, i_slt, "a-64"), X OP("sltu", IF_R, i_sltu, "a-67"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X}; X X/* X * The bcond opcode instruction table. X */ Xinstrn optab_bcond[] = X{ X OP("bltz", IF_I, i_bltz, "a-22"), X OP("bgez", IF_I, i_bgez, "a-18"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("bltzal", IF_I, i_undef, "a-23"), X OP("bgezal", IF_I, i_undef, "a-19"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X}; X X/* X * The cop0 opcode instruction table. X */ Xinstrn optab_cop0[] = X{ X OP("", IF_U, i_undef, "????"), X OP("tlbr", IF_U, i_undef, "a-82"), X OP("tlbwi", IF_U, i_undef, "a-83"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("tlbwr", IF_U, i_undef, "a-84"), X OP("", IF_U, i_undef, "????"), X X OP("tlbp", IF_U, i_undef, "a-81"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("rfe", IF_U, i_undef, "a-59"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X}; X X/* X * The cop1 group1 opcode instruction table. X */ Xinstrn optab_cop1_group1[] = X{ X OP("mfc1", IF_M1, i_mfc1, "b-21"), X OP("mfc1", IF_M1, i_mfc1, "b-21"), X OP("cfc1", IF_C1, i_cfc1, "b-14"), X OP("cfc1", IF_C1, i_cfc1, "b-14"), X OP("mtc1", IF_M1, i_mtc1, "b-23"), X OP("mtc1", IF_M1, i_mtc1, "b-23"), X OP("ctc1", IF_C1, i_ctc1, "b-15"), X OP("ctc1", IF_C1, i_ctc1, "b-15"), X X OP("bc1f", IF_I1, i_bc1f, "b-10"), X OP("bc1t", IF_I1, i_bc1t, "b-11"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("bc1f", IF_I1, i_bc1f, "b-10"), X OP("bc1t", IF_I1, i_bc1t, "b-11"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X}; X X/* X * The cop1 group2 opcode instruction table. X */ Xinstrn optab_cop1_group2[] = X{ X OP("add.fmt", IF_R1, i_addfmt, "b-09"), X OP("sub.fmt", IF_R1, i_subfmt, "b-26"), X OP("mul.fmt", IF_R1, i_mulfmt, "b-24"), X OP("div.fmt", IF_R1, i_divfmt, "b-19"), X OP("", IF_U, i_undef, "????"), X OP("abs.fmt", IF_R1, i_absfmt, "b-08"), X OP("mov.fmt", IF_R1, i_movfmt, "b-22"), X OP("neg.fmt", IF_R1, i_negfmt, "b-25"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("cvt.s", IF_R1, i_cvts, "b-17"), X OP("cvt.d", IF_R1, i_cvtd, "b-16"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("cvt.w", IF_R1, i_cvtw, "b-18"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X OP("", IF_U, i_undef, "????"), X X OP("c.f", IF_R1, i_undef, "b-12"), X OP("c.un", IF_R1, i_undef, "b-12"), X OP("c.eq", IF_R1, i_ceq, "b-12"), X OP("c.ueq", IF_R1, i_undef, "b-12"), X OP("c.olt", IF_R1, i_colt, "b-12"), X OP("c.ult", IF_R1, i_cult, "b-12"), X OP("c.ole", IF_R1, i_cole, "b-12"), X OP("c.ule", IF_R1, i_cule, "b-12"), X X OP("c.sf", IF_R1, i_undef, "b-12"), X OP("c.ngle", IF_R1, i_undef, "b-12"), X OP("c.seq", IF_R1, i_undef, "b-12"), X OP("c.ngl", IF_R1, i_undef, "b-12"), X OP("c.lt", IF_R1, i_clt, "b-12"), X OP("c.nge", IF_R1, i_undef, "b-12"), X OP("c.le", IF_R1, i_cle, "b-12"), X OP("c.ngt", IF_R1, i_undef, "b-12"), X X OP("", IF_U, i_undef, "????"), X}; X Xinstrn * Xgetip(i) Xunsigned long i; X{ X unsigned long opindex; X instrn *ip; X X opindex = i_to_op(i); X X switch (opindex) X { X case 0: /* special */ X ip = &optab_special[i_to_funct(i)]; X break; X X case 1: /* bcond */ X ip = &optab_bcond[i_to_rt(i)]; X break; X X case 16: /* coprocessor 0 */ X ip = &optab_cop0[i_to_funct(i) & 0x1F]; X break; X X case 17: /* coprocessor 1 */ X if (is_cop1_group1(i)) X ip = &optab_cop1_group1[i_to_cop1_group1(i)]; X else X ip = &optab_cop1_group2[i_to_cop1_group2(i)]; X break; X X default: X ip = &optab[opindex]; X break; X } X X return ip; X} END_OF_FILE if test 16629 -ne `wc -c <'optab.c'`; then echo shar: \"'optab.c'\" unpacked with wrong size! fi # end of 'optab.c' fi if test -f 'process.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'process.c'\" else echo shar: Extracting \"'process.c'\" \(25029 characters\) sed "s/^X//" >'process.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include "register.h" X#include "symtab.h" X#include "diblock.h" X#include "instrn.h" X#include "process.h" X#include "wcache.h" X#include "nels.h" X X#if 0 X#endif /* 0 */ X#define SPECIAL_MEMCPY X X#if defined(SPECIAL_MEMCPY) X#define Wmemcpy(to,from,n) \ X{ \ X if \ X ( \ X (n) == sizeof(unsigned long) \ X && \ X (((unsigned long)(from)) & 0x3) == 0x0 \ X && \ X (((unsigned long)(to)) & 0x3) == 0x0 \ X ) \ X *(unsigned long *)(to) = *(unsigned long *)(from); \ X else \ X (void)memcpy((to), (from), (n)); \ X} X#else /* defined(SPECIAL_MEMCPY) */ X#define Wmemcpy(to,from,n) (void)memcpy((to), (from), (n)) X#endif /* defined(SPECIAL_MEMCPY) */ X Xextern void couldnot(); Xextern void warning(); Xextern char *strdup(); Xextern char *say_register(); Xextern int symtab_open(); Xextern int symtab_close(); Xextern char *symtab_text_address(); Xextern LDFILE *my_ldopen(); Xextern int histo_init(); Xextern char *proc_text_address(); Xextern int clear_decoded_page(); X Xextern int errno; X Xextern FILE *outfp; X Xextern int Cflag; Xextern int Hflag; Xextern int Vflag; X Xprocess P; Xint give_warnings = 1; X Xstatic int ld_section_read(); Xstatic int procimput(); X Xint Xprocopen(adotout) Xchar *adotout; X{ X FILE *fp; X LDFILE *ldptr; X struct filehdr *fhp; X unsigned short sectindx; X SCNHDR secthead; X AOUTHDR adotout_header; X int i; X int length; X X if ((P.p_adotout = strdup(adotout)) == (char *)0) X return -1; X X P.p_pid = getpid(); X X /* X * Read the executable and initialise X * our memory image of it. X */ X X if ((ldptr = my_ldopen(adotout, (LDFILE *)0)) == (LDFILE *)0) X return -1; X X if (ISARCHIVE(TYPE(ldptr))) X { X vcouldnot("interpret contents of archive \"%s\"", adotout); X (void)ldclose(ldptr); X return -1; X } X X fhp = &HEADER(ldptr); X X if (!ISCOFF(fhp->f_magic)) X { X vcouldnot("interpret contents of non-COFF executable \"%s\"", adotout); X (void)ldclose(ldptr); X return -1; X } X X /* X * Determine the entry point of the process. X */ X if (ldohseek(ldptr) != SUCCESS) X { X vcouldnot("seek to start of optional header structure in executable \"%s\"", adotout); X (void)ldclose(ldptr); X return -1; X } X X if (FREAD(&adotout_header, sizeof(adotout_header), 1, ldptr) != 1) X { X vcouldnot("read optional header structure from executable \"%s\"", adotout); X (void)ldclose(ldptr); X return -1; X } X X if (Vflag) X { X fprintf(outfp, "magic == 0%o\n", adotout_header.magic); X fprintf(outfp, "vstamp == 0x%x(%d)\n", adotout_header.vstamp, adotout_header.vstamp); X fprintf(outfp, "tsize == 0x%x(%d)\n", adotout_header.tsize, adotout_header.tsize); X fprintf(outfp, "dsize == 0x%x(%d)\n", adotout_header.dsize, adotout_header.dsize); X fprintf(outfp, "bsize == 0x%x(%d)\n", adotout_header.bsize, adotout_header.bsize); X fprintf(outfp, "entry == 0x%x(%d)\n", adotout_header.entry, adotout_header.entry); X fprintf(outfp, "text_start == 0x%x(%d)\n", adotout_header.text_start, adotout_header.text_start); X fprintf(outfp, "data_start == 0x%x(%d)\n", adotout_header.data_start, adotout_header.data_start); X fprintf(outfp, "bss_start == 0x%x(%d)\n", adotout_header.bss_start, adotout_header.bss_start); X fprintf(outfp, "gprmask == 0x%x(%d)\n", adotout_header.gprmask, adotout_header.gprmask); X fprintf(outfp, "gp_value == 0x%x(%d)\n", adotout_header.gp_value, adotout_header.gp_value); X } X X if (adotout_header.magic == OMAGIC) X P.p_text_region_is_readonly = 0; X else X P.p_text_region_is_readonly = 1; X X /* X * Initialise the PC as the process's entry point. X */ X P.p_entry_point = adotout_header.entry; X X P.p_text_region_min = adotout_header.text_start; X P.p_text_region_limit = P.p_text_region_min + adotout_header.tsize - 1; X P.p_text_region_wlimit = P.p_text_region_limit + 1 - sizeof(unsigned long); X P.p_text_region = calloc(adotout_header.tsize / sizeof(unsigned long), sizeof(unsigned long)); X if (P.p_text_region == (unsigned char *)0) X { X vcouldnot("grow text space to size %d bytes", adotout_header.tsize); X (void)ldclose(ldptr); X return -1; X } X X P.p_data_region_min = adotout_header.data_start; X X /* X * Initialise GP to the process's gp value. X */ X if (quiet_procsput(R_GP, adotout_header.gp_value) == -1) X { X (void)ldclose(ldptr); X return -1; X } X X /* X * Read each COFF section in turn, copying the data of those X * that are required to memory. X */ X sectindx = 1; X while (ldshread(ldptr, sectindx, §head) == SUCCESS) X { X if (Vflag) X { X fprintf X ( X outfp, X "read section %d: name=\"%s\",paddr=0x%x,vaddr=0x%x,size=%d,scnptr=%d,relptr=%d,lnnoptr=%d,nreloc=%d,nlnno=%d,flags=0x%x\n", X sectindx, X §head.s_name[0], X secthead.s_paddr, X secthead.s_vaddr, X secthead.s_size, X secthead.s_scnptr, X secthead.s_relptr, X secthead.s_lnnoptr, X secthead.s_nreloc, X secthead.s_nlnno, X secthead.s_flags X ); X } X X switch (secthead.s_flags & 0xF) X { X case STYP_REG: X if (Vflag) X fprintf(outfp, "STYP_REG: allocated, relocated, loaded\n"); X break; X X case STYP_DSECT: X if (Vflag) X fprintf(outfp, "STYP_DSECT: not allocated, relocated, not loaded\n"); X break; X X case STYP_NOLOAD: X if (Vflag) X fprintf(outfp, "STYP_NOLOAD: allocated, relocated, not loaded\n"); X break; X X case STYP_GROUP: X if (Vflag) X fprintf(outfp, "STYP_GROUP: grouped\n"); X break; X X case STYP_PAD: X if (Vflag) X fprintf(outfp, "STYP_PAD: not allocated, not relocated, loaded\n"); X break; X X default: X vcouldnot("recognise section type 0x%x", secthead.s_flags & 0xF); X (void)ldclose(ldptr); X return -1; X } X X switch (secthead.s_flags & ~0xF) X { X case STYP_COPY: X if (Vflag) X fprintf(outfp, "STYP_COPY: not allocated, not relocated, loaded\n"); X break; X X case STYP_TEXT: X if (Vflag) X fprintf(outfp, "STYP_TEXT: text only\n"); X break; X X case STYP_DATA: X if (Vflag) X fprintf(outfp, "STYP_DATA: data only\n"); X break; X X case STYP_BSS: X if (Vflag) X fprintf(outfp, "STYP_BSS: bss only\n"); X break; X X case STYP_RDATA: X if (Vflag) X fprintf(outfp, "STYP_RDATA: read only data only\n"); X break; X X case STYP_SDATA: X if (Vflag) X fprintf(outfp, "STYP_SDATA: small data only\n"); X break; X X case STYP_SBSS: X if (Vflag) X fprintf(outfp, "STYP_SBSS: small bss only\n"); X break; X X case STYP_UCODE: X if (Vflag) X fprintf(outfp, "STYP_UCODE: ucode only\n"); X break; X X case STYP_LIT8: X if (Vflag) X fprintf(outfp, "STYP_LIT8: literal pool for 8-byte literals\n"); X break; X X case STYP_LIT4: X if (Vflag) X fprintf(outfp, "STYP_LIT4: literal pool for 4-byte literals\n"); X break; X X case S_NRELOC_OVFL: X if (Vflag) X fprintf(outfp, "S_NRELOC_OVFL: s_nreloc overflowed, the value is in v_addr of the first entry\n"); X break; X X case STYP_LIB: X if (Vflag) X fprintf(outfp, "STYP_LIB: section is a .lib section\n"); X break; X X case STYP_INIT: X if (Vflag) X fprintf(outfp, "STYP_INIT: section only contains the text instructions for the .init sec.\n"); X break; X X default: X vcouldnot("recognise section type 0x%x", secthead.s_flags & ~0xF); X (void)ldclose(ldptr); X return -1; X } X X if (strcmp(§head.s_name[0], ".lib") == 0) X { X vcouldnot("handle executable containing a .lib (call to shared library) section"); X return -1; X } X else if (strcmp(§head.s_name[0], ".data") == 0) X { X /* X * Initialise the start of the writable data. X */ X if (quiet_procwrdataput(secthead.s_vaddr) == -1) X { X (void)ldclose(ldptr); X return -1; X } X } X else if (strcmp(§head.s_name[0], ".bss") == 0) X { X /* X * Initialise The Break. X */ X if (procbreakput(secthead.s_vaddr + secthead.s_size) == -1) X { X vcouldnot("set break to 0x%x", secthead.s_vaddr + secthead.s_size); X (void)ldclose(ldptr); X return -1; X } X } X X if (ld_section_read(ldptr, secthead.s_scnptr, secthead.s_vaddr, secthead.s_size) == -1) X { X (void)ldclose(ldptr); X return -1; X } X X sectindx++; X } X X if (symtab_open(ldptr, adotout, &P.p_symtab) == -1) X { X (void)ldclose(ldptr); X return -1; X } X X /* X * Close the executable file. X */ X if (ldclose(ldptr) != SUCCESS) X { X vcouldnot("close executable \"%s\"", adotout); X return -1; X } X X if (Hflag) X { X if (histo_init(P.p_text_region_min, P.p_text_region_limit + 1 - P.p_text_region_min) == -1) X return -1; X } X X P.p_stack_region_min = STACK_MAX + 1; X X return 0; X} X Xstatic Xint Xld_section_read(srce_ldptr, srce_offset, dest_offset, count) XLDFILE *srce_ldptr; Xlong srce_offset; Xlong dest_offset; Xlong count; X{ X unsigned char buf[64 * 1024]; X X if (srce_offset == (long)0) X (void)memset(&buf[0], 0x00, sizeof(buf)); X else X { X if (FSEEK(srce_ldptr, srce_offset, SEEK_SET) != 0) X { X vcouldnot("FSEEK to offset %d in source file in ld_section_read()", srce_offset); X return -1; X } X } X X while (count > 0) X { X int chunk; X X chunk = (count >= sizeof(buf)) ? sizeof(buf) : count; X X if (srce_offset != (long)0) X { X if (FREAD(&buf[0], chunk, 1, srce_ldptr) != 1) X { X vcouldnot("FREAD from source file in ld_section_read()"); X return -1; X } X } X X if (procimput(dest_offset, &buf[0], chunk) == -1) X return -1; X X count -= chunk; X dest_offset += chunk; X } X X return 0; X} X Xint Xprocclose() X{ X FILE *fp; X int mi; X int i; X X if (P.p_stack_region != (unsigned char *)0) X (void)free(P.p_stack_region); X X if (P.p_data_region != (unsigned char *)0) X (void)free(P.p_data_region); X X if (P.p_text_region != (unsigned char *)0) X (void)free(P.p_text_region); X X if (symtab_close(&P.p_symtab) == -1) X return -1; X X if (P.p_adotout != (char *)0) X { X (void)free(P.p_adotout); X P.p_adotout = (char *)0; X } X X (void)fflush(outfp); X X return 0; X} X Xvoid Xprocsput_trace(regi, v) Xint regi; Xunsigned long v; X{ X if (Cflag) X { X switch (regi) X { X case R_0: X break; X X case R_GP: X case R_RA: X case R_SP: X fprintf(outfp, "%6d:\t%s = %s;\n", P.p_pid, say_register(regi), proc_text_address(v)); X break; X X default: X fprintf(outfp, "%6d:\t%s = 0x%08x;\n", P.p_pid, say_register(regi), v); X break; X } X } X else X fprintf(outfp, "\t\tprocsput(%d, %s, %d)\n", P.p_pid, say_register(regi), v); X} X Xvoid Xprocsget_trace(regi, r) Xint regi; Xunsigned long r; X{ X if (Cflag) X { X#if 0 X switch (regi) X { X case R_RA: X fprintf(outfp, "%6d:\t? = %s /* %s */;\n", P.p_pid, say_register(regi), proc_text_address(r)); X break; X X default: X fprintf(outfp, "%6d:\t? = %s /* 0x%08x */;\n", P.p_pid, say_register(regi), r); X break; X } X#endif /* 0 */ X } X else X fprintf(outfp, "\t\tprocsget(%d, %s, %d)\n", P.p_pid, say_register(regi), r); X} X Xvoid Xprocmput_trace(offset, cp, length) Xunsigned long offset; Xchar *cp; Xint length; X{ X if (Cflag) X { X while (length >= sizeof(int)) X { X fprintf(outfp, "%6d:\t*(int *)%s = 0x%08x;\n", P.p_pid, proc_text_address(offset), *(int *)cp); X length -= sizeof(int); X cp += sizeof(int); X offset += sizeof(int); X } X X while (length >= sizeof(short)) X { X fprintf(outfp, "%6d:\t*(short *)%s = 0x%04x;\n", P.p_pid, proc_text_address(offset), *(short *)cp); X length -= sizeof(short); X cp += sizeof(short); X offset += sizeof(short); X } X X while (length >= sizeof(char)) X { X fprintf(outfp, "%6d:\t*(char *)%s = 0x%02x;\n", P.p_pid, proc_text_address(offset), *(unsigned char *)cp); X length -= sizeof(char); X cp += sizeof(char); X offset += sizeof(char); X } X } X else X fprintf(outfp, "\t\t\tprocmput(pid=%d,offset=%d,length=%d)\n", P.p_pid, offset, length); X} X Xvoid Xprocmget_trace(offset, cp, length) Xunsigned long offset; Xchar *cp; Xint length; X{ X if (Cflag) X { X#if 0 X while (length >= sizeof(int)) X { X fprintf(outfp, "%6d:\t? = *(int *)%s /* 0x%08x */;\n", P.p_pid, proc_text_address(offset), *(int *)cp); X length -= sizeof(int); X cp += sizeof(int); X offset += sizeof(int); X } X X while (length >= sizeof(short)) X { X fprintf(outfp, "%6d:\t? = *(short *)%s /* 0x%04x */;\n", P.p_pid, proc_text_address(offset), *(short *)cp); X length -= sizeof(short); X cp += sizeof(short); X offset += sizeof(short); X } X X while (length >= sizeof(char)) X { X fprintf(outfp, "%6d:\t? = *(char *)%s /* 0x%02x */;\n", P.p_pid, proc_text_address(offset), *(unsigned char *)cp); X length -= sizeof(char); X cp += sizeof(char); X offset += sizeof(char); X } X#endif /* 0 */ X } X else X fprintf(outfp, "\t\t\tprocmget(pid=%d,offset=%d,length=%d)\n", P.p_pid, offset, length); X} X Xvoid Xprocsget_warning(regi) Xint regi; X{ X warning("read from kernel-reserved register %s", say_register(regi)); X} X Xint Xprocbreakput(newbrk) Xunsigned long newbrk; X{ X unsigned long new_region_size; X unsigned char *new_region; X X wcache_clear(); X X new_region_size = newbrk - P.p_data_region_min; X X if ((new_region = calloc(new_region_size, 1)) == (unsigned char *)0) X return -1; X X if (P.p_data_region != (unsigned char *)0) X { X unsigned long p_data_region_size; X X p_data_region_size = P.p_data_region_limit + 1 - P.p_data_region_min; X X (void)memcpy(new_region, P.p_data_region, (new_region_size < p_data_region_size) ? new_region_size : p_data_region_size); X (void)free(P.p_data_region); X } X X P.p_data_region = new_region; X P.p_data_region_limit = newbrk - 1; X P.p_data_region_wlimit = P.p_data_region_limit + 1 - sizeof(unsigned long); X X return 0; X} X Xint Xprocbreakget(oldbrkp) Xunsigned long *oldbrkp; X{ X *oldbrkp = P.p_data_region_limit + 1; X X return 0; X} X Xint Xprocwrdataput(newwrdata) Xunsigned long newwrdata; X{ X P.p_writable_data = newwrdata; X X return 0; X} X Xint Xprocwrdataget(oldwrdatap) Xunsigned long *oldwrdatap; X{ X *oldwrdatap = P.p_writable_data; X X return 0; X} X Xstatic Xint Xprocimput(offset, cp, length) Xunsigned long offset; Xunsigned char *cp; Xint length; X{ X unsigned long limit; X int i; X X limit = offset + length - 1; X X if (limit <= P.p_text_region_limit) X { X if ((i = offset - P.p_text_region_min) < 0) X { X vcouldnot("write %d byte%s at text address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X Wmemcpy(&P.p_text_region[i], cp, length); X } X else if (limit <= DATA_MAX) X { X if ((i = offset - P.p_data_region_min) < 0) X { X vcouldnot("write %d byte%s at data address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X if (limit > P.p_data_region_limit) X { X if (procbreakput(limit + 1) == -1) X { X vcouldnot("set break to 0x%x", limit + 1); X return -1; X } X } X X Wmemcpy(&P.p_data_region[i], cp, length); X } X else X { X /* X * Stack space or above. X */ X vcouldnot("write %d byte%s at non-text, non-data address 0x%x: illegal (too big) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X return 0; X} X X/* X * Grow the stack down to include 'offset'. X */ Xint Xproc_grow_stack(dipc, offset) Xdinstrn *dipc; Xunsigned long offset; X{ X unsigned long new_stack_region_size; X unsigned char *new_stack_region; X X wcache_clear(); X X if (offset < STACK_MIN) X { X GLOBALdipc = dipc; X vcouldnot("grow stack to address 0x%x: below 0x%x", offset, STACK_MIN); X return -1; X } X X new_stack_region_size = STACK_MAX + 1 - offset; X new_stack_region_size += 4096; /* slop */ X new_stack_region_size &= ~0xF; /* Quadword aligned */ X X if ((new_stack_region = calloc(new_stack_region_size / 16, sizeof(unsigned char) * 16)) == (unsigned char *)0) X { X GLOBALdipc = dipc; X vcouldnot("grow stack to %d bytes", new_stack_region_size); X return -1; X } X X if (P.p_stack_region != (unsigned char *)0) X { X unsigned long p_stack_region_size; X X p_stack_region_size = STACK_MAX + 1 - P.p_stack_region_min; X X (void)memcpy(&new_stack_region[new_stack_region_size - p_stack_region_size], P.p_stack_region, p_stack_region_size); X (void)free(P.p_stack_region); X } X X P.p_stack_region = new_stack_region; X P.p_stack_region_min = STACK_MAX + 1 - new_stack_region_size; X X return 0; X} X Xint Xquiet_procmget(dipc, offset, cp, length) Xdinstrn *dipc; Xunsigned long offset; Xunsigned char *cp; Xint length; X{ X unsigned long limit; X int i; X X if (length == 0) X return 0; X X limit = offset + length - 1; X X if (limit <= P.p_text_region_limit) X { X if ((i = offset - P.p_text_region_min) < 0) X { X GLOBALdipc = dipc; X vcouldnot("read %d byte%s at text address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X Wmemcpy(cp, &P.p_text_region[i], length); X } X else if (limit <= P.p_data_region_limit) X { X if ((i = offset - P.p_data_region_min) < 0) X { X GLOBALdipc = dipc; X vcouldnot("read %d byte%s at data address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X Wmemcpy(cp, &P.p_data_region[i], length); X } X else if (limit <= STACK_MAX) X { X if ((i = offset - P.p_stack_region_min) < 0) X { X if (proc_grow_stack(dipc, offset) == -1) X return -1; X X i = offset - P.p_stack_region_min; X } X X Wmemcpy(cp, &P.p_stack_region[i], length); X } X else X { X /* X * Hole above Stack space. X */ X GLOBALdipc = dipc; X vcouldnot("read %d byte%s at data address 0x%x: illegal (i.e. too big) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X return 0; X} X Xint Xprocmget(dipc, offset, cp, length) Xdinstrn *dipc; Xunsigned long offset; Xunsigned char *cp; Xint length; X{ X int result; X X result = quiet_procmget(dipc, offset, cp, length); X X if (Mflag) X procmget_trace(offset, cp, length); X X return result; X} X Xint Xproc_mem_contiguous(offset, length, p) Xunsigned long offset; Xint length; Xchar **p; X{ X unsigned long limit; X X limit = offset + length - 1; X X if X ( X offset >= P.p_text_region_min X && X limit <= P.p_text_region_limit X ) X { X if (p != (char **)0) X *p = &P.p_text_region[offset - P.p_text_region_min]; X return 1; X } X X if X ( X offset >= P.p_data_region_min X && X limit <= P.p_data_region_limit X ) X { X if (p != (char **)0) X *p = &P.p_data_region[offset - P.p_data_region_min]; X return 1; X } X X if X ( X offset >= P.p_stack_region_min X && X limit <= STACK_MAX X ) X { X if (p != (char **)0) X *p = &P.p_stack_region[offset - P.p_stack_region_min]; X return 1; X } X X return 0; X} X Xint Xquiet_procmput(dipc, offset, cp, length) Xdinstrn *dipc; Xunsigned long offset; Xunsigned char *cp; Xint length; X{ X unsigned long limit; X int i; X X if (length == 0) X return 0; X X limit = offset + length - 1; X X if (offset < P.p_text_region_min) X { X /* X * Hole before text. X */ X GLOBALdipc = dipc; X vcouldnot("write %d byte%s at address 0x%x: illegal (i.e. too small) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X if (offset <= P.p_text_region_limit) X { X int tlength; X X /* X * Text (or Readonly Data?) space. X */ X if (P.p_text_region_is_readonly) X { X GLOBALdipc = dipc; X vcouldnot("write %d byte%s at address 0x%x: readonly (text or data) address", length, (length == 1) ? "" : "s", offset); X return -1; X } X X if (limit > P.p_text_region_limit) X tlength = P.p_text_region_limit + 1 - offset; X else X tlength = length; X X Wmemcpy(&P.p_text_region[offset - P.p_text_region_min], cp, tlength); X X /* X * Disable decoded instructions for this range. X */ X { X int t; X unsigned long o; X X t = tlength; X o = offset; X X while (t > 0) X { X int remainder; X X if (clear_decoded_page(dipc, o, &remainder) == -1) X return -1; X X o += remainder; X t -= remainder; X } X } X X offset += tlength; X cp += tlength; X length -= tlength; X X if (length == 0) X return 0; X } X X if ((i = offset - P.p_data_region_min) < 0) X { X /* X * Hole between text and data. X */ X GLOBALdipc = dipc; X vcouldnot("write %d byte%s at address 0x%x: illegal (i.e. unmapped) address between text and data regions", length, (length == 1) ? "" : "s", offset); X return -1; X } X X if (limit <= P.p_data_region_limit) X { X /* X * Data space. X */ X Wmemcpy(&P.p_data_region[i], cp, length); X return 0; X } X X if (limit <= STACK_MAX) X { X /* X * Stack space. X */ X if ((i = offset - P.p_stack_region_min) < 0) X { X if (proc_grow_stack(dipc, offset) == -1) X return -1; X X i = offset - P.p_stack_region_min; X } X X Wmemcpy(&P.p_stack_region[i], cp, length); X return 0; X } X X /* X * Hole above Stack space. X */ X GLOBALdipc = dipc; X vcouldnot("write %d byte%s starting at address 0x%x: illegal (i.e. too big) address", length, (length == 1) ? "" : "s", offset); X return -1; X} X Xint Xprocmput(dipc, offset, cp, length) Xdinstrn *dipc; Xunsigned long offset; Xunsigned char *cp; Xint length; X{ X if (Mflag) X procmput_trace(offset, cp, length); X X return quiet_procmput(dipc, offset, cp, length); X} X Xchar * Xproc_text_address(text_address) Xunsigned long text_address; X{ X return symtab_text_address((P.p_adotout == (char *)0) ? (symtab *)0 : &P.p_symtab, text_address); X} X Xint Xquiet_procsget(r, v) Xint r; Xunsigned long *v; X{ X int saved_Rflag; X X saved_Rflag = Rflag; X Rflag = 0; X procsget(r, *v); X Rflag = saved_Rflag; X X return 0; X} X Xint Xquiet_procsput(r, v) Xint r; Xunsigned long v; X{ X int saved_Rflag; X X saved_Rflag = Rflag; X Rflag = 0; X procsput(r, v); X Rflag = saved_Rflag; X X return 0; X} X Xint Xquiet_procbreakget(v) Xunsigned long *v; X{ X int result; X int saved_Rflag; X X saved_Rflag = Rflag; X Rflag = 0; X result = procbreakget(v); X Rflag = saved_Rflag; X X return result; X} X Xint Xquiet_procbreakput(v) Xunsigned long v; X{ X int result; X int saved_Rflag; X X saved_Rflag = Rflag; X Rflag = 0; X result = procbreakput(v); X Rflag = saved_Rflag; X X return result; X} X Xint Xquiet_procwrdataput(v) Xunsigned long v; X{ X int result; X int saved_Rflag; X X saved_Rflag = Rflag; X Rflag = 0; X result = procwrdataput(v); X Rflag = saved_Rflag; X X return result; X} X Xint Xmagic_ok(filename) Xchar *filename; X{ X int fd; X int saved_errno; X unsigned short smagic; X X saved_errno = errno; X X if ((fd = open(filename, O_RDONLY)) == -1) X return 0; X X if (read(fd, (unsigned char *)&smagic, sizeof(smagic)) != sizeof(smagic)) X { X saved_errno = errno; X (void)close(fd); X errno = saved_errno; X return 0; X } X X (void)close(fd); X X if X ( X smagic == MIPSEBMAGIC X || X smagic == MIPSELMAGIC X || X smagic == SMIPSEBMAGIC X || X smagic == SMIPSELMAGIC X || X smagic == MIPSEBUMAGIC X || X smagic == MIPSELUMAGIC X || X smagic == MIPSEBMAGIC_2 X || X smagic == MIPSELMAGIC_2 X || X smagic == SMIPSEBMAGIC_2 X || X smagic == SMIPSELMAGIC_2 X || X smagic == MIPSEBMAGIC_3 X || X smagic == MIPSELMAGIC_3 X || X smagic == SMIPSEBMAGIC_3 X || X smagic == SMIPSELMAGIC_3 X ) X { X errno = saved_errno; X return 1; X } X X if X ( X ((unsigned char *)&smagic)[0] == '#' X && X ((unsigned char *)&smagic)[1] == '!' X ) X { X errno = saved_errno; X return 2; X } X X errno = ENOEXEC; X X return 0; X} X Xint Xinterpreter_ok(filename) Xchar *filename; X{ X int fd; X int saved_errno; X char interpreter_data[64 + 1]; X char *new_filename; X char *cp; X X saved_errno = errno; X X if ((fd = open(filename, O_RDONLY)) == -1) X return 0; X X /* X * Skip the magic number -- we know X * it looks ok. X */ X if (lseek(fd, 2, 0) == -1) X { X saved_errno = errno; X (void)close(fd); X errno = saved_errno; X return 0; X } X X bzero(&interpreter_data[0], sizeof(interpreter_data)); X X if (read(fd, &interpreter_data[0], sizeof(interpreter_data) - 1) <= 0) X { X saved_errno = errno; X (void)close(fd); X errno = saved_errno; X return 0; X } X X (void)close(fd); X X /* X * Skip leading white space. X */ X for (new_filename = &interpreter_data[0]; *new_filename == ' ' || *new_filename == '\t'; new_filename++) X ; X X /* X * Terminate the filename with a '\0'. X */ X for (cp = new_filename; *cp != ' ' && *cp != '\t' && *cp != '\n' && *cp != '\0'; cp++) X ; X X *cp = '\0'; X X if (magic_ok(new_filename) == 1) X { X errno = saved_errno; X return 1; X } X X errno = ENOEXEC; X X return 0; X} X Xint Xget_interpreter_data(filename, interpreter_namep, interpreter_argp) Xchar *filename; Xchar **interpreter_namep; Xchar **interpreter_argp; X{ X int saved_errno; X int fd; X static char interpreter_data[64 + 1]; X char *new_filename; X char *cp; X int savedc; X X saved_errno = errno; X X if ((fd = open(filename, O_RDONLY)) == -1) X { X (void)close(fd); X errno = saved_errno; X return -1; X } X X bzero(&interpreter_data[0], sizeof(interpreter_data)); X X if (read(fd, &interpreter_data[0], sizeof(interpreter_data) - 1) < 3) X { X (void)close(fd); X errno = saved_errno; X return -1; X } X X (void)close(fd); X X errno = saved_errno; X X if X ( X interpreter_data[0] != '#' X || X interpreter_data[1] != '!' X ) X return -1; X X /* X * Skip leading white space. X */ X for (new_filename = &interpreter_data[2]; *new_filename == ' ' || *new_filename == '\t'; new_filename++) X ; X X *interpreter_namep = new_filename; X X /* X * Terminate the filename with a '\0'. X */ X for (cp = new_filename; *cp != ' ' && *cp != '\t' && *cp != '\n' && *cp != '\0'; cp++) X ; X X savedc = *cp; X *cp++ = '\0'; X X if (savedc == '\n' || savedc == '\0') X return 0; X X /* X * Skip any further white space. X */ X while (*cp == ' ' || *cp == '\t') X cp++; X X if (*cp == '\n' || *cp == '\0') X return 0; X X *interpreter_argp = cp; X X /* X * Terminate the argument with a '\0'. X */ X while (*cp != '\n' && *cp != '\0') X cp++; X X *cp = '\0'; X X return 0; X} X Xint Xis_a_shared_library(filename) Xchar *filename; X{ X /* X * TODO: check for shared libraries. X */ X return 0; X} END_OF_FILE if test 25029 -ne `wc -c <'process.c'`; then echo shar: \"'process.c'\" unpacked with wrong size! fi # end of 'process.c' fi echo shar: End of archive 4 \(of 8\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0