001 // This file is part of the program FRYSK. 002 // 003 // Copyright 2006, 2007, 2008, IBM Corp. 004 // Copyright 2007, 2008, Red Hat Inc. 005 // 006 // Contributed by 007 // Jose Flavio Aguilar Paulino (joseflavio@gmail.com) 008 // 009 // FRYSK is free software; you can redistribute it and/or modify it 010 // under the terms of the GNU General Public License as published by 011 // the Free Software Foundation; version 2 of the License. 012 // 013 // FRYSK is distributed in the hope that it will be useful, but 014 // WITHOUT ANY WARRANTY; without even the implied warranty of 015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 016 // General Public License for more details. 017 // 018 // You should have received a copy of the GNU General Public License 019 // along with FRYSK; if not, write to the Free Software Foundation, 020 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 021 // 022 // In addition, as a special exception, Red Hat, Inc. gives You the 023 // additional right to link the code of FRYSK with code not covered 024 // under the GNU General Public License ("Non-GPL Code") and to 025 // distribute linked combinations including the two, subject to the 026 // limitations in this paragraph. Non-GPL Code permitted under this 027 // exception must only link to the code of FRYSK through those well 028 // defined interfaces identified in the file named EXCEPTION found in 029 // the source code files (the "Approved Interfaces"). The files of 030 // Non-GPL Code may instantiate templates or use macros or inline 031 // functions from the Approved Interfaces without causing the 032 // resulting work to be covered by the GNU General Public 033 // License. Only Red Hat, Inc. may make changes or additions to the 034 // list of Approved Interfaces. You must obey the GNU General Public 035 // License in all respects for all of the FRYSK code and other code 036 // used in conjunction with FRYSK except the Non-GPL Code covered by 037 // this exception. If you modify this file, you may extend this 038 // exception to your version of the file, but you are not obligated to 039 // do so. If you do not wish to provide this exception without 040 // modification, you must delete this exception statement from your 041 // version and license this file solely under the GPL without 042 // exception. 043 044 package frysk.isa.corefiles; 045 046 import frysk.sys.ProcessIdentifierFactory; 047 import java.util.Iterator; 048 import inua.eio.ArrayByteBuffer; 049 import inua.eio.ByteBuffer; 050 import lib.dwfl.ElfEHeader; 051 import lib.dwfl.ElfEMachine; 052 import lib.dwfl.ElfNhdr; 053 import lib.dwfl.ElfNhdrType; 054 import lib.dwfl.ElfPrFPRegSet; 055 import lib.dwfl.ElfPrpsinfo; 056 import lib.dwfl.ElfPrstatus; 057 import frysk.isa.registers.PPC32Registers; 058 import frysk.isa.registers.Register; 059 import frysk.isa.banks.BankRegister; 060 import frysk.isa.banks.LinuxPPCRegisterBanks; 061 import frysk.proc.Proc; 062 import frysk.proc.Task; 063 import frysk.sys.proc.CmdLineBuilder; 064 import frysk.sys.proc.Stat; 065 066 /** 067 * PPC32LinuxElfCorefile. Extends LinuxCorefile. Fill in 068 * specific PPC32 information for corefiles. 069 * 070 */ 071 public class PPC32LinuxElfCorefile extends LinuxElfCorefile { 072 073 Proc process; 074 075 Task[] blockedTasks; 076 077 int size; 078 /** 079 * 080 * LinuxElfCoreFile. Construct a corefile from a given process, and that process's 081 * tasks that have been blocked. 082 * 083 * @param process - The parent process to construct the core from. 084 * @param blockedTasks - The process's tasks, in a stopped state 085 */ 086 public PPC32LinuxElfCorefile(Proc process, Task blockedTasks[]) { 087 super(process, blockedTasks); 088 this.process = process; 089 this.blockedTasks = blockedTasks; 090 this.size = 32; 091 } 092 093 /* (non-Javadoc) 094 * @see frysk.util.LinuxElfCorefile#writeNotePrpsinfo(lib.dwfl.ElfNhdr, frysk.proc.Proc) 095 */ 096 protected void writeNotePrpsinfo(ElfNhdr nhdrEntry, Proc process) { 097 098 int pid = process.getPid(); 099 100 ElfPrpsinfo prpsInfo = new ElfPrpsinfo(this.size); 101 Stat processStat = new Stat().scan(ProcessIdentifierFactory.create(pid)); 102 103 // Set state and name. 104 prpsInfo.setPrState(processStat.state); 105 prpsInfo.setPrSname(processStat.state); 106 107 108 // If state = Z then set zombie flag 109 if (processStat.state == 'Z') 110 prpsInfo.setPrZomb((char)1); 111 else 112 prpsInfo.setPrZomb((char)0); 113 114 115 String midStr = String.valueOf(processStat.nice); 116 prpsInfo.setPrNice(midStr.charAt(0)); 117 118 119 // Set rest of prpsinfo 120 prpsInfo.setPrFlag(processStat.flags); 121 prpsInfo.setPrUid(process.getUID()); 122 prpsInfo.setPrGid(process.getGID()); 123 124 prpsInfo.setPrPid(pid); 125 prpsInfo.setPrPpid(processStat.ppid.intValue()); 126 prpsInfo.setPrPgrp(processStat.pgrp); 127 128 prpsInfo.setPrSid(processStat.session); 129 prpsInfo.setPrFname(processStat.comm); 130 131 // Build command line 132 class BuildCmdLine extends CmdLineBuilder { 133 String prettyArgs = ""; 134 135 public void buildArgv(String[] argv) { 136 137 for (int i = 0; i < argv.length; i++) 138 prettyArgs += (argv[i] + " "); 139 140 // Trim end space 141 if (prettyArgs.length() > 0) 142 prettyArgs = prettyArgs.substring(0, 143 prettyArgs.length() - 1); 144 } 145 } 146 BuildCmdLine cmdLine = new BuildCmdLine(); 147 cmdLine.construct(ProcessIdentifierFactory.create(pid)); 148 149 // Set it 150 prpsInfo.setPrPsargs(cmdLine.prettyArgs); 151 152 // Write entry 153 nhdrEntry.setNhdrDesc(ElfNhdrType.NT_PRPSINFO, prpsInfo); 154 } 155 156 /* (non-Javadoc) 157 * @see frysk.util.LinuxElfCorefile#writeNotePrstatus(lib.dwfl.ElfNhdr, frysk.proc.Task) 158 */ 159 protected void writeNotePrstatus(ElfNhdr nhdrEntry, Task task) { 160 161 ElfPrstatus prStatus = new ElfPrstatus(this.size); 162 163 Stat processStat = new Stat().scan(ProcessIdentifierFactory.create(task.getTid())); 164 165 // Set initial prstatus data 166 prStatus.setPrPid(task.getTid()); 167 prStatus.setPrPpid(processStat.ppid.intValue()); 168 prStatus.setPrPgrp(processStat.pgrp); 169 prStatus.setPrSid(processStat.session); 170 prStatus.setPrSigPending(processStat.signal); 171 172 // Order for these registers is found in /usr/include/asm/user.h 173 // This is not the same order that frysk iterators print out, nor 174 // are the names are the same. Create a string[] map to bridge 175 // gap between frysk and core file register order. 176 177 // The number of total common registers in PPC/PPC64 including nip, msr, 178 // etc. Defined in the asm-ppc/elf.h. 179 Register[] ptracePpcRegMap = { 180 PPC32Registers.NIP, PPC32Registers.MSR, PPC32Registers.ORIGR3, 181 PPC32Registers.CTR, PPC32Registers.LR, PPC32Registers.XER, 182 PPC32Registers.CCR, PPC32Registers.MQ, PPC32Registers.TRAP, 183 PPC32Registers.DAR, PPC32Registers.DSISR, PPC32Registers.RESULT, 184 PPC32Registers.GPR0, PPC32Registers.GPR1, PPC32Registers.GPR2, 185 PPC32Registers.GPR3, PPC32Registers.GPR4, PPC32Registers.GPR5, 186 PPC32Registers.GPR6, PPC32Registers.GPR7, PPC32Registers.GPR8, 187 PPC32Registers.GPR9, PPC32Registers.GPR10, PPC32Registers.GPR11, 188 PPC32Registers.GPR12, PPC32Registers.GPR13, PPC32Registers.GPR14, 189 PPC32Registers.GPR15, PPC32Registers.GPR16, PPC32Registers.GPR17, 190 PPC32Registers.GPR18, PPC32Registers.GPR19, PPC32Registers.GPR20, 191 PPC32Registers.GPR21, PPC32Registers.GPR22, PPC32Registers.GPR23, 192 PPC32Registers.GPR24, PPC32Registers.GPR25, PPC32Registers.GPR26, 193 PPC32Registers.GPR27, PPC32Registers.GPR28, PPC32Registers.GPR29, 194 PPC32Registers.GPR30, PPC32Registers.GPR31}; 195 196 197 // Set GP register info 198 int index = 0; 199 int arraySize = 0; 200 int regSize; 201 int wordSize = task.getISA().wordSize(); 202 int elfNGREG = 48; 203 204 // Allocate space in array. Even though there are some registers < wordSize, they still have 205 // to sit in a wordSize area 206 for (int l = 0; l < ptracePpcRegMap.length; l++) 207 if (ptracePpcRegMap[l].getType().getSize() < wordSize) 208 arraySize +=wordSize; 209 else 210 arraySize +=ptracePpcRegMap[l].getType().getSize(); 211 212 int blankRegisterIndex = (elfNGREG - ptracePpcRegMap.length) * wordSize; 213 214 byte[] byteOrderedRegister= new byte[arraySize+blankRegisterIndex]; 215 216 // Populate array, using wordSize as minimum size 217 for (int i = 0; i < ptracePpcRegMap.length; i++) { 218 regSize = ptracePpcRegMap[i].getType().getSize(); 219 if (regSize < wordSize) 220 regSize = wordSize; 221 task.access(ptracePpcRegMap[i], 0, regSize, byteOrderedRegister, index, false); 222 index += regSize; 223 } 224 225 prStatus.setPrGPRegisterBuffer(byteOrderedRegister); 226 227 // Write it 228 nhdrEntry.setNhdrDesc(ElfNhdrType.NT_PRSTATUS, prStatus); 229 } 230 231 /* 232 * (non-Javadoc) 233 * 234 * @see frysk.util.LinuxElfCorefile#writeNoteFPRegset(lib.dwfl.ElfNhdr, 235 * frysk.proc.Task) 236 */ 237 protected void writeNoteFPRegset(ElfNhdr nhdrEntry, Task task) { 238 239 ElfPrFPRegSet xfpRegSet = new ElfPrFPRegSet(); 240 241 final int bankSize = 260; 242 final int maxRegSize = 8; 243 byte[] scratch = new byte[maxRegSize]; 244 byte[] byteOrderedRegister= new byte[bankSize]; 245 ArrayByteBuffer byteOrderedBuffer = new ArrayByteBuffer(byteOrderedRegister); 246 247 Iterator registerIterator = LinuxPPCRegisterBanks.FPREGS32.entryIterator(); 248 while (registerIterator.hasNext()) { 249 BankRegister bankRegister = ((BankRegister)registerIterator.next()); 250 Register register = bankRegister.getRegister(); 251 task.access(register, 0, register.getType().getSize(), scratch, 0, false); 252 bankRegister.access(byteOrderedBuffer, 0, maxRegSize, scratch, 0, true); 253 } 254 255 byteOrderedBuffer.get(byteOrderedRegister); 256 257 xfpRegSet.setFPRegisterBuffer(byteOrderedRegister); 258 259 // Write it 260 nhdrEntry.setNhdrDesc(ElfNhdrType.NT_FPREGSET, xfpRegSet); 261 262 ElfPrFPRegSet fpRegSet = new ElfPrFPRegSet(); 263 264 // Write FP Register info over wholesae. Do not interpret. 265 ByteBuffer registerMaps[] = task.getRegisterBuffersFIXME(); 266 byte[] regBuffer = new byte[(int) registerMaps[1].capacity()]; 267 registerMaps[1].get(regBuffer); 268 269 fpRegSet.setFPRegisterBuffer(regBuffer); 270 271 // Write it 272 nhdrEntry.setNhdrDesc(ElfNhdrType.NT_FPREGSET, fpRegSet); 273 } 274 275 /* (non-Javadoc) 276 * @see frysk.util.LinuxElfCorefile#writeNotePRXFPRegset(lib.dwfl.ElfNhdr, frysk.proc.Task) 277 */ 278 protected boolean writeNotePRXFPRegset(ElfNhdr nhdrEntry, Task task) { 279 return false; 280 } 281 282 /* (non-Javadoc) 283 * @see frysk.util.LinuxElfCorefile#getElfMachineType() 284 */ 285 protected byte getElfMachineType() { 286 return ElfEMachine.EM_PPC; 287 } 288 289 /* (non-Javadoc) 290 * @see frysk.util.LinuxElfCorefile#getElfMachineClass() 291 */ 292 protected byte getElfMachineClass() { 293 return ElfEHeader.CLASS32; 294 } 295 }