001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2007, 2008 Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package frysk.proc.dead;
041    
042    import lib.dwfl.ElfPrstatus;
043    import lib.dwfl.ElfPrFPRegSet;
044    import lib.dwfl.ElfPrXFPRegSet;
045    import inua.eio.ByteBuffer;
046    import inua.eio.ArrayByteBuffer;
047    import inua.eio.ByteOrder;
048    import frysk.isa.ISA;
049    import frysk.isa.banks.RegisterBanks;
050    import frysk.isa.registers.RegistersFactory;
051    import frysk.rsl.Log;
052    
053    public class LinuxCoreTask extends DeadTask {
054    
055        private static final Log fine = Log.fine(LinuxCoreTask.class);
056        private final LinuxCoreProc parent;
057    
058        public ByteBuffer getMemory() {
059            // XXX: Get the Proc's memory (memory maps). Task and register
060            // information is handled differently (through notes) in core
061            // files. There's a potential here for task to have its own
062            // memory maps in some architectures, but not in the current
063            // ISAs. In an attempt to save system resources, get a
064            // reference to the proc's maps for now.
065    
066            fine.log(this,"getMemory() called by ",Log.CALLER);
067            return parent.getMemory();
068        }
069    
070        static private RegisterBanks simulateRegisterBanks(ElfPrstatus elfTask,
071                                                           ElfPrFPRegSet elfFPRegs,
072                                                           ElfPrXFPRegSet elfXFPRegs,
073                                                           ISA isa) {
074            // XXX: Potentially this information should be constructed in
075            // CorefileRegisterBanksFactory. However that would require
076            // the factory to know about elf constructs which is not
077            // desirable.
078            ByteBuffer[] bankBuffers = new ByteBuffer[4];
079    
080            // Create an empty page
081            byte[] emptyBuffer = new byte[4096];
082            for (int i=0; i<emptyBuffer.length; i++)
083                emptyBuffer[i]=0;
084    
085            // Get ISA specific data
086            ByteOrder byteOrder = isa.order();
087            int  wordSize = isa.wordSize();
088        
089            // Set GP Registers
090            bankBuffers[0] = new ArrayByteBuffer(elfTask.getRawCoreRegisters());
091            bankBuffers[0].order(byteOrder);
092            bankBuffers[0].wordSize(wordSize);
093    
094            // The following register banks are either fake (blank page) or
095            // actual core data. As corefiles may or may not contain various
096            // parts of register data, and there is an expectation throughout
097            // Frysk that each task will always provide register data
098            // regardless, we have to preset an empty page to avoid NPEs.
099    
100            // If Floating Point Register are present
101            if (elfFPRegs != null)
102                bankBuffers[1] = new ArrayByteBuffer(elfFPRegs.getFPRegisterBuffer());
103            else
104                bankBuffers[1] = new ArrayByteBuffer(emptyBuffer);
105    
106            bankBuffers[1].order(byteOrder);
107            bankBuffers[1].wordSize(wordSize);
108    
109            // If X Floating Point Register are present
110            if (elfXFPRegs != null)
111                bankBuffers[2] = new ArrayByteBuffer(elfXFPRegs.getXFPRegisterBuffer());
112            else
113                bankBuffers[2] = new ArrayByteBuffer(emptyBuffer);
114    
115            bankBuffers[2].order(byteOrder);
116            bankBuffers[2].wordSize(wordSize);
117    
118            // XXX: Other register banks need to be filled in.
119            bankBuffers[3] = new ArrayByteBuffer(emptyBuffer);
120    
121            return CorefileRegisterBanksFactory.create(isa, bankBuffers);
122        }
123    
124        /**
125         * Create a new unattached Task.
126         */
127        LinuxCoreTask(LinuxCoreProc proc, ElfPrstatus elfTask, ElfPrFPRegSet
128                      elfFPRegs, ElfPrXFPRegSet elfXFPRegs, ISA isa) {
129            super(proc, elfTask.getPrPid(), isa,
130                  simulateRegisterBanks(elfTask, elfFPRegs, elfXFPRegs, isa));
131            this.parent = proc;
132        }
133    
134        public long getPC() {
135            return getRegister(RegistersFactory
136                               .getRegisters(getISA())
137                               .getProgramCounter());
138        }
139    }