public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Move LinkMap reading code to frysk.solib.
@ 2008-03-10 21:53 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-03-10 21:53 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  dd417143986b806ef499396b016145a6d20905c7 (commit)
      from  5492baa03cd955076e3b9cc5305def492de72920 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit dd417143986b806ef499396b016145a6d20905c7
Author: Andrew Cagney <cagney@redhat.com>
Date:   Mon Mar 10 17:51:40 2008 -0400

    Move LinkMap reading code to frysk.solib.
    
    frysk-core/frysk/proc/dead/ChangeLog
    2008-03-10  Andrew Cagney  <cagney@redhat.com>
    
    	* LinuxCoreInfo.java: Refactor link-map code to
    	frysk.solib.LinkMapFactory and frysk.solib.DynamicSegment.
    	(addEnhancedMapData): Use LinkMapFactory.
    	(getLinkmapAddress): Moved to frysk.solib.
    	(getDynamicSegmentAddress): Ditto.
    	(getExeInterpreterAddress): Ditto.
    	(getExeDynamicSegmentAddress): Ditto.
    	(getExeEntryPoint): Ditto.
    	(getExeInterpreterName): Ditto.
    	(getCorefileEntryPoint): Ditto.
    	(DynamicSegmentTuple): Ditto.
    	(Linkmap): Ditto.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/proc/dead/ChangeLog               |   15 +
 frysk-core/frysk/proc/dead/LinuxCoreInfo.java      |  273 +------------------
 frysk-core/frysk/solib/ChangeLog                   |   13 +
 frysk-core/frysk/solib/DynamicSegment.java         |  128 +++++++++
 .../registers/Register.java => solib/LinkMap.java} |   35 +--
 frysk-core/frysk/solib/LinkMapFactory.java         |  277 ++++++++++++++++++++
 frysk-core/frysk/solib/package.html                |   15 +
 7 files changed, 478 insertions(+), 278 deletions(-)
 create mode 100644 frysk-core/frysk/solib/ChangeLog
 create mode 100644 frysk-core/frysk/solib/DynamicSegment.java
 copy frysk-core/frysk/{isa/registers/Register.java => solib/LinkMap.java} (81%)
 create mode 100644 frysk-core/frysk/solib/LinkMapFactory.java
 create mode 100644 frysk-core/frysk/solib/package.html

First 500 lines of diff:
diff --git a/frysk-core/frysk/proc/dead/ChangeLog b/frysk-core/frysk/proc/dead/ChangeLog
index 5b66c15..7a34a1f 100644
--- a/frysk-core/frysk/proc/dead/ChangeLog
+++ b/frysk-core/frysk/proc/dead/ChangeLog
@@ -1,3 +1,18 @@
+2008-03-10  Andrew Cagney  <cagney@redhat.com>
+
+	* LinuxCoreInfo.java: Refactor link-map code to
+	frysk.solib.LinkMapFactory and frysk.solib.DynamicSegment.
+	(addEnhancedMapData): Use LinkMapFactory.
+	(getLinkmapAddress): Moved to frysk.solib.
+	(getDynamicSegmentAddress): Ditto.
+	(getExeInterpreterAddress): Ditto.
+	(getExeDynamicSegmentAddress): Ditto.
+	(getExeEntryPoint): Ditto.
+	(getExeInterpreterName): Ditto.
+	(getCorefileEntryPoint): Ditto.
+	(DynamicSegmentTuple): Ditto.
+	(Linkmap): Ditto.
+
 2008-03-04  Andrew Cagney  <cagney@redhat.com>
 
 	* DeadHost.java: Update to match Host.
diff --git a/frysk-core/frysk/proc/dead/LinuxCoreInfo.java b/frysk-core/frysk/proc/dead/LinuxCoreInfo.java
index 6ba97a3..8d19246 100644
--- a/frysk-core/frysk/proc/dead/LinuxCoreInfo.java
+++ b/frysk-core/frysk/proc/dead/LinuxCoreInfo.java
@@ -43,7 +43,6 @@ import java.util.List;
 import java.util.LinkedList;
 import java.io.File;
 import lib.dwfl.Elf;
-import lib.dwfl.ElfSection;
 import lib.dwfl.ElfPrAuxv;
 import lib.dwfl.ElfCommand;
 import lib.dwfl.ElfData;
@@ -60,6 +59,8 @@ import frysk.proc.Auxv;
 import frysk.sys.proc.AuxvBuilder;
 import frysk.proc.MemoryMap;
 import java.util.Iterator;
+import frysk.solib.LinkMapFactory;
+import frysk.solib.LinkMap;
 
 /**
  * Extract from a core file all the information needed to construct
@@ -305,11 +306,7 @@ class LinuxCoreInfo {
     private static void addEnhancedMapData(File coreFile, File exeFile,
 					   MapAddressHeader[] metaData,
 					   Elf exeElf, Auxv[] auxv) {
-	fine.log("constructEnhancedMapMetadata");
-
-	// Find Dynamic Segment
-	DynamicSegmentTuple dynamicTuple
-	    = getDynamicSegmentAddress(auxv, exeElf);
+	fine.log("addEnhancedMapData");
 
 	// Create a temporary, noncache resetting view into the
 	// corefile memory so that the link-map table can be
@@ -317,46 +314,16 @@ class LinuxCoreInfo {
 	CorefileByteBuffer tempMemory = new CorefileByteBuffer(coreFile,
 							       metaData);
     
-	// From that segment address, find linkmap table.
-	long linkmapAddress = getLinkmapAddress(tempMemory, dynamicTuple);
-
-	// No link map, hence no libraries have so far been loaded
-	// (core was taken while the program was at the entry point or
-	// shortly after).  This is ok, the executable is still being
-	// used for things like the exe path.
-	if (linkmapAddress == 0)
+	LinkMap[] linkMaps = LinkMapFactory.extractLinkMaps(exeElf, exeFile,
+							    tempMemory, auxv);
+	fine.log("linkMaps", linkMaps);
+	if (linkMaps == null)
+	    // No link map, hence no libraries have so far been loaded
+	    // (core was taken while the program was at the entry
+	    // point or shortly after).  This is ok, the executable is
+	    // still being used for things like the exe path.
 	    return;
 
-	// Edge case: Save interp name as it is not included the
-	// linkmap as it is loaded by the kernel.
-	String interpName = getExeInterpreterName(exeElf);
-
-	// Edge case: Get interp address so when we traverse the
-	// linkmap it can be paired with its name
-	long interpAddr = getExeInterpreterAddress(exeElf); 
-
-	// Build the link-map table from the link-map table address
-	fine.log("Building linkmap");
-	class BuildLinkMap extends LinkmapBuilder {
-	    List list = new LinkedList();
-	    public void buildMap(long l_addr, long l_ld, long saddr,
-				 String name) {
-		fine.log("New linkmap item: l_addr", l_addr,
-			 "l_ld", l_ld, "s_addr", l_addr, "name", name);
-		list.add(new Linkmap(l_addr, l_ld, saddr, name));
-	    }
-	}
-	BuildLinkMap linkMap = new BuildLinkMap();
-	linkMap.construct(linkmapAddress, tempMemory);
-	for (Iterator i = linkMap.list.iterator(); i.hasNext(); ) {
-	    Linkmap tempMap = (Linkmap) i.next();
-	    if (tempMap.s_addr == interpAddr) {
-		fine.log("Found interpretator at linkmap address",
-			 tempMap.s_addr);
-		tempMap.name = interpName;
-	    }
-	}
-
 	// From the list of solibs in the linkamp,  build
 	// maps for each one.
 	class BuildSOMaps extends SOLibMapBuilder {
@@ -372,9 +339,10 @@ class LinuxCoreInfo {
 	}
 
 	BuildSOMaps SOMaps = new BuildSOMaps();
-	for (Iterator i = linkMap.list.iterator(); i.hasNext(); ) {
-	    Linkmap singleLinkMap = (Linkmap) i.next();
-	    if ((!singleLinkMap.name.equals("")) && (!singleLinkMap.name.equals("[vdso]")))
+	for (int i = 0; i < linkMaps.length; i++) {
+	    LinkMap singleLinkMap = linkMaps[i];
+	    if ((!singleLinkMap.name.equals(""))
+		&& (!singleLinkMap.name.equals("[vdso]")))
 		SOMaps.construct(new File(singleLinkMap.name),
 				 singleLinkMap.l_addr);
 	    if (singleLinkMap.name.equals("[vdso]"))
@@ -404,191 +372,6 @@ class LinuxCoreInfo {
     }
 
     /**
-     * Helper function to return the backing core file's dynamic
-     * segment address and size
-     */
-    private static DynamicSegmentTuple getDynamicSegmentAddress(Auxv[] auxv,
-								Elf exeElf) {
-	fine.log("getDynamicSegmentAddress");
-	// If we do not have an executable, we cannot find the dynamic
-	// segment in the corefile.
-	long coreEntryPoint = getCorefileEntryPoint(auxv);
-	long exeEntryPoint = getExeEntryPoint(exeElf);
-	DynamicSegmentTuple exeDynamicTuple
-	    = getExeDynamicSegmentAddress(exeElf);
-
-	// Calculate relocated segment address, if necessary.
-	if (exeDynamicTuple != null)
-	    exeDynamicTuple.addr = exeDynamicTuple.addr + 
-		coreEntryPoint - exeEntryPoint;
-    
-	fine.log("getDynamicSegmentAddress tuple",
-		 exeDynamicTuple.addr, "size", exeDynamicTuple.size);
-	return exeDynamicTuple;
-    
-    }
-
-    /**
-     * Helper function to find the backing executable's dynamic
-     * address and size
-     **/
-    private static DynamicSegmentTuple getExeDynamicSegmentAddress(Elf exeElf) {
-    	fine.log("getExeDynamicSegmentAddress");
-	DynamicSegmentTuple exeDynamicAddr = null;
-	ElfEHeader eHeader = exeElf.getEHeader();
-	// Find dynamic segment by iterating through program segment
-	// headers
-	for (int headerCount = 0; headerCount < eHeader.phnum; headerCount++) {
-	    ElfPHeader pHeader = exeElf.getPHeader(headerCount);
-	    // Found the dynamic section
-	    if (pHeader.type == ElfPHeader.PTYPE_DYNAMIC) {
-		exeDynamicAddr = new DynamicSegmentTuple(pHeader.vaddr,
-							 pHeader.filesz);
-		break;
-	    }
-	}
-	fine.log("getDynamicExeSegmentAddress tuple",
-		 exeDynamicAddr.addr, "size", exeDynamicAddr.size);
-	return exeDynamicAddr;
-    }
-
-    /**
-     * Helper function to locate the link map table in the 
-     * core file. This is located in the dynamic segment table
-     * at the address specified by the DT_DEBUG field.
-     */
-    private static long getLinkmapAddress(CorefileByteBuffer internalMem,
-					  DynamicSegmentTuple tuple) {
-	fine.log("getLinkmapAddress");
-	final int DT_DEBUG = 21;
-	if (tuple == null) {
-	    fine.log("Dynamic segment is null, linkmap set to 0");
-	    return 0;
-
-	}
-
-	long dynSegmentEndAddress = tuple.addr + tuple.size;
-	long dtDebugAddress = 0;
-	long actualAddress = 0;
-	long dtTest;
-
-	// Position the core-file's memory at the corefile's dynamic
-	// segment.
-	internalMem.position(tuple.addr);
-
-	// find DT_DEBUG field in table. The tabke is two
-	// words. One is the DT_ tag and the other
-	// is the address of that DT_ tag table type.
-	while (internalMem.position() < dynSegmentEndAddress) {
-	    // Get tag and test if it is DT_DEBUG
-	    dtTest = internalMem.getUWord();
-	    if (dtTest == DT_DEBUG) {
-		// If it is record the address in the 
-		// next word.
-		dtDebugAddress = internalMem.getUWord();
-		break;
-	    }
-	
-	    // Otherwise, move on.
-	    internalMem.getUWord();
-	}
-
-	if (dtDebugAddress != 0) {
-	    // Go to address that DT_DEBUG tag 
-	    // specified.
-	    internalMem.position(dtDebugAddress);
-
-	    // discard first word at that address;
-	    internalMem.getInt();
-	    long pos = internalMem.position();
-	    int wordSize = internalMem.wordSize();
-	    if (pos % wordSize > 0)
-		pos = (pos - (pos % wordSize))+wordSize;
-	
-	    internalMem.position(pos);
-	    actualAddress = internalMem.getUWord();
-	}
-
-	fine.log("Linkmap address is", actualAddress);
-	return actualAddress;
-    }
-
-    /**
-     * Helper function to locate and report the backing Executables
-     * entry point
-     */
-    private static long getExeEntryPoint(Elf exeElf) {
-	ElfEHeader eHeader = exeElf.getEHeader();
-	if (eHeader == null)
-	    throw new RuntimeException("executable is not elf");
-	return eHeader.entry;
-    }
-
-    /**
-     * Helper function to locate and report the backing Executables
-     * interpeters address.
-     */
-    private static long getExeInterpreterAddress(Elf exeElf) {
-	fine.log("getExeInterpreterAddress");
-	long interpreterAddress = 0;
-	ElfEHeader eHeader = exeElf.getEHeader();
-	// Find .interp segment by passing through progream segment
-	// header
-	for (int headerCount = 0; headerCount < eHeader.phnum; headerCount++) {
-	    ElfPHeader pHeader = exeElf.getPHeader(headerCount);
-	    if (pHeader.type == ElfPHeader.PTYPE_INTERP) {
-		interpreterAddress = pHeader.vaddr;
-		break;
-	    }
-	}
-	fine.log("Interpreter Addr", interpreterAddress);
-	return interpreterAddress;
-    }
-
-    /**
-     * Helper function to locate and report the backing Executables
-     * interpeters name
-     */
-    private static String getExeInterpreterName(Elf exeElf) {
-	fine.log("getExeInterpreterName");
-	String interpName = "";
-	ElfEHeader eHeader = exeElf.getEHeader();
-	// Find .interp segment by passing through progream segment
-	// header
-	for (int headerCount = 0; headerCount < eHeader.phnum; headerCount++) {
-	    ElfPHeader pHeader = exeElf.getPHeader(headerCount);
-	    if (pHeader.type == ElfPHeader.PTYPE_INTERP) {
-		ElfSection interpSection = exeElf.getSection((long)headerCount);
-		ElfData data = interpSection.getData();
-		interpName = new String(data.getBytes());
-		interpName = interpName.trim();
-		break;
-	    }
-	}
-	fine.log("Interpreter name", interpName);
-	return interpName;
-    }
-
-    /**
-     * Helper function to locate and report the backing corefile's
-     * entry point
-     */
-    private static long getCorefileEntryPoint(Auxv[] auxv) {
-	fine.log("getCorefileEntryPoint");
-	// Need auxv data
-	long entryPoint = 0;
-	// Find the Auxv ENTRY data
-	for (int i = 0; i < auxv.length; i++) {
-	    if (auxv[i].type == inua.elf.AT.ENTRY) {
-		entryPoint = auxv[i].val;
-		break;
-	    }
-	}
-	fine.log("Corefile Entrypoint", entryPoint);
-	return entryPoint;
-    }
-
-    /**
      * Helper function to locate and report the backing corefile's
      * VDSO address
      */
@@ -606,32 +389,6 @@ class LinuxCoreInfo {
 	return vdsoEntryPoint;
     }
 
-
-
-    // Private class to hold Dynamic Segment address tuple
-    private static class DynamicSegmentTuple {
-	long addr = 0;
-	long size = 0;
-	public DynamicSegmentTuple(long addr, long size) {
-	    this.addr = addr;
-	    this.size = size;
-	}
-    }
-
-    private static class Linkmap {
-	long l_addr = 0;
-	long l_dyn = 0;
-	long s_addr = 0;
-	String name = "";
-	Linkmap(long l_addr, long l_dyn, long s_addr, String name) {
-	    this.l_addr = l_addr;
-	    this.l_dyn = l_dyn;
-	    this.s_addr = s_addr;
-	    this.name = name;
-	}
-    }
-
-
     /**
      * Find and create the core tasks.
      */
diff --git a/frysk-core/frysk/solib/ChangeLog b/frysk-core/frysk/solib/ChangeLog
new file mode 100644
index 0000000..9f7c90e
--- /dev/null
+++ b/frysk-core/frysk/solib/ChangeLog
@@ -0,0 +1,13 @@
+2008-03-10  Andrew Cagney  <cagney@redhat.com>
+
+	* LinkMap.java: Extract from frysk.proc.dead.LinuxCoreInfo.
+	* LinkMapFactory.java: Ditto.
+	* DynamicSegment.java: Ditto.
+
+\f
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/frysk-core/frysk/solib/DynamicSegment.java b/frysk-core/frysk/solib/DynamicSegment.java
new file mode 100644
index 0000000..e773894
--- /dev/null
+++ b/frysk-core/frysk/solib/DynamicSegment.java
@@ -0,0 +1,128 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2007, 2008 Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.solib;
+
+import lib.dwfl.Elf;
+import lib.dwfl.ElfEHeader;
+import lib.dwfl.ElfPHeader;
+import frysk.rsl.Log;
+import frysk.proc.Auxv;
+
+/**
+ * Extract from a core file all the information needed to construct
+ * and maintain a corefile Host, Proc, and Task.  The Elf objects used
+ * to extract the information are all closed.
+ */
+
+class DynamicSegment {
+    private static final Log fine = Log.fine(DynamicSegment.class);
+
+    final long addr;
+    final long size;
+
+    /**
+     * Helper function to return the backing core file's dynamic
+     * segment address and size
+     */
+    DynamicSegment(Auxv[] auxv, Elf exeElf) {
+	fine.log("DynamicSegment auxv", auxv, "exe", exeElf);
+	// If we do not have an executable, we cannot find the dynamic
+	// segment in target memory.
+	long auxvEntryPoint = getEntryPoint(auxv);
+	long exeEntryPoint = getEntryPoint(exeElf);
+	ElfPHeader exeDynamicSegment = getDynamicSegment(exeElf);
+
+	// Calculate relocated segment address, if necessary.
+	addr = exeDynamicSegment.vaddr + auxvEntryPoint - exeEntryPoint;
+	size = exeDynamicSegment.filesz;
+	fine.log("getDynamicSegmentAddress addr", addr, "size", size);
+    }
+
+    /**
+     * Helper function to find the backing executable's dynamic
+     * segment.
+     **/
+    private static ElfPHeader getDynamicSegment(Elf exeElf) {
+    	fine.log("getExeDynamicSegmentAddress");
+	ElfEHeader eHeader = exeElf.getEHeader();
+	// Find dynamic segment by iterating through program segment
+	// headers
+	for (int headerCount = 0; headerCount < eHeader.phnum; headerCount++) {
+	    ElfPHeader pHeader = exeElf.getPHeader(headerCount);
+	    // Found the dynamic section
+	    if (pHeader.type == ElfPHeader.PTYPE_DYNAMIC) {
+		fine.log("getDynamicSegmentAddress found", pHeader);
+		return pHeader;
+	    }
+	}
+	return null;
+    }
+
+    /**
+     * Helper function to locate and report the backing Executables
+     * entry point
+     */
+    private static long getEntryPoint(Elf exeElf) {
+	fine.log("getEntryPoint", exeElf);
+	ElfEHeader eHeader = exeElf.getEHeader();
+	if (eHeader == null)
+	    throw new RuntimeException("executable is not elf");
+	fine.log("elf entry-point", eHeader.entry);
+	return eHeader.entry;
+    }
+
+    /**
+     * Helper function to locate and report the AUXV entry point.
+     */
+    private static long getEntryPoint(Auxv[] auxv) {
+	fine.log("getEntryPoint", auxv);
+	// Need auxv data
+	long entryPoint = 0;
+	// Find the Auxv ENTRY data
+	for (int i = 0; i < auxv.length; i++) {
+	    if (auxv[i].type == inua.elf.AT.ENTRY) {
+		entryPoint = auxv[i].val;
+		break;
+	    }
+	}


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-03-10 21:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-10 21:53 [SCM] master: Move LinkMap reading code to frysk.solib cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).