public inbox for frysk-cvs@sourceware.org help / color / mirror / Atom feed
From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Move LinkMap reading code to frysk.solib. Date: Mon, 10 Mar 2008 21:53:00 -0000 [thread overview] Message-ID: <20080310215314.21124.qmail@sourceware.org> (raw) 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
reply other threads:[~2008-03-10 21:53 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080310215314.21124.qmail@sourceware.org \ --to=cagney@sourceware.org \ --cc=frysk-cvs@sourceware.org \ --cc=frysk@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).