dbgmoddwarf.cpp revision 1b1592b7ed076977cda6d2b1fae320626609b836
* you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. /******************************************************************************* *******************************************************************************/ /******************************************************************************* * Defined Constants And Macros * *******************************************************************************/ /** @name Standard DWARF Line Number Opcodes /** @name Extended DWARF Line Number Opcodes /******************************************************************************* * Structures and Typedefs * *******************************************************************************/ /** End of valid parts (exclusive). */ * Abbreviation cache entry. /** Whether this entry is filled in or not. */ /** Whether there are children or not. */ /** Offset into the abbrev section of the specification pairs. */ /** Pointer to an abbreviation cache entry. */ /** Pointer to a const abbreviation cache entry. */ * The instance data of the DWARF reader. /** The debug container containing doing the real work. */ /** Pointer to back to the debug info module (no reference ofc). */ /** DWARF debug info sections. */ /** The file offset of the part. */ /** The size of the part. */ /** The memory mapping of the part. */ /** The offset into the abbreviation section of the current cache. */ /** The number of cached abbreviations we've allocated space for. */ /** Used for range checking cache lookups. */ /** Array of cached abbreviations, indexed by code. */ /** Used by rtDwarfAbbrev_Lookup when the result is uncachable. */ /** Pointer to instance data of the DWARF reader. */ * DWARF cursor for reading byte data. /** The current position. */ /** The number of bytes left to read. */ /** The number of bytes left to read in the current unit. */ /** The DWARF debug info reader instance. */ /** Set if this is 64-bit DWARF, clear if 32-bit. */ /** Set if the format endian is native, clear if endian needs to be /** The size of a native address. */ /** The cursor status code. This is VINF_SUCCESS until some error /** The start of the area covered by the cursor. * Used for repositioning the cursor relative to the start of a section. */ /** Pointer to a DWARF section reader. */ * DWARF line number program state. /** Virtual Line Number Machine Registers. */ /** @name Include Path Table (0-based) /** @name File Name Table (0-based, dummy zero entry) /** The DWARF debug info reader instance. */ /** Pointer to a DWARF line number program state. */ /** @callback_method_impl{FNRTLDRENUMSEGS} */ Log((
"Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n",
* Calls pfnSegmentAdd for each segment in the executable image. * @returns IPRT status code. * @param pMod The debug module. * Loads a DWARF section from the image file. * @returns IPRT status code. * @param pThis The DWARF instance. * @param enmSect The section to load. * Don't load stuff twice. * Sections that are not present cannot be loaded, treat them like they * Sections must be readable with the current image interface. * Unloads a DWARF section previously mapped by rtDbgModDwarfLoadSection. * @returns IPRT status code. * @param pThis The DWARF instance. * @param enmSect The section to unload. * Converts to UTF-8 or otherwise makes sure it's valid UTF-8. * @returns IPRT status code. * @param pThis The DWARF instance. * @param ppsz Pointer to the string pointer. May be * Convers a link address into a segment+offset or RVA. * @returns IPRT status code. * @param pThis The DWARF instance. * @param LinkAddress The address to convert.. * @param piSeg The segment index. * @param poffSeg Where to return the segment offset. * Reads a 8-bit unsigned integer and advances the cursor. * @returns 8-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on read error. * Reads a 16-bit unsigned integer and advances the cursor. * @returns 16-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on read error. * Reads a 32-bit unsigned integer and advances the cursor. * @returns 32-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on read error. * Reads a 64-bit unsigned integer and advances the cursor. * @returns 64-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on read error. * Reads an unsigned LEB128 encoded number. * @returns unsigned 64-bit number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue The value to return on error. * Special case - single byte. * Reads a signed LEB128 encoded number. * @returns signed 64-bit number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param sErrValue The value to return on error. * Special case - single byte. /* Sign extend the value. */ * Reads an unsigned LEB128 encoded number, max 32-bit width. * @returns unsigned 32-bit number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue The value to return on error. * Reads a signed LEB128 encoded number, max 32-bit width. * @returns signed 32-bit number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param sErrValue The value to return on error. * Skips a LEB128 encoded number. * @returns IPRT status code. * @param pCursor The cursor. * Reads a zero terminated string, advancing the cursor beyond the terminator. * @returns Pointer to the string. * @param pCursor The cursor. * @param pszErrValue What to return if the string isn't terminated * before the end of the unit. * Reads an unsigned DWARF half number. * @returns The number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on error. * Reads an unsigned DWARF byte number. * @returns The number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on error. * Reads a signed DWARF byte number. * @returns The number. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on error. * Reads a unsigned DWARF offset value. * @returns The value. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on error. * Reads a unsigned DWARF native offset value. * @returns The value. On error RTDWARFCURSOR::rc is set and @a * @param pCursor The cursor. * @param uErrValue What to return on error. * Gets the unit length, updating the unit length member and DWARF bitness * @returns The unit length. * @param pCursor The cursor. * Read the initial length. * Set the unit length, quitely fixing bad lengths. * Calculates the section offset corresponding to the current cursor position. * @returns 32-bit section offset. If out of range, RTDWARFCURSOR::rc will be * set and UINT32_MAX returned. * @param pCursor The cursor. * Calculates an absolute cursor position from one relative to the current * @returns The absolute cursor position. * @param pCursor The cursor. * @param offRelative The relative position. Must be a positive * Advances the cursor to the given position. * @returns IPRT status code. * @param pCursor The cursor. * @param pbNewPos The new position - returned by * rtDwarfCursor_CalcPos(). * Check if the cursor is at the end of the current DWARF unit. * @returns @c true if at the end, @c false if not. * @param pCursor The cursor. * Skips to the end of the current unit. * @returns IPRT status code. * @param pCursor The cursor. * Check if the cursor is at the end of the section (or whatever the cursor is * @returns @c true if at the end, @c false if not. * @param pCursor The cursor. * Initialize a section reader cursor. * @returns IPRT status code. * @param pCursor The cursor. * @param pThis The dwarf module. * @param enmSect The name of the section to read. /** @todo ask the image about the endian used as well as the address * Initialize a section reader cursor with an offset. * @returns IPRT status code. * @param pCursor The cursor. * @param pThis The dwarf module. * @param enmSect The name of the section to read. * @param offSect The offset into the section. * Deletes a section reader initialized by rtDwarfCursor_Init. * @param pCursor The section reader. /* ... and a drop of poison. */ * @returns IPRT status code. * @param pLnState The line number program state. * @param pszFilename The name of the file. * @param idxInc The include path index. * Resize the array if necessary. * Adds a line to the table and resets parts of the state (DW_LNS_copy). * @returns IPRT status code * @param pLnState The line number program state. :
"<bad file name index>";
/* Ignore address conflicts for now. */ * Reset the program to the start-of-sequence state. * @param pLnState The line number program state. * Runs the line number program. * @returns IPRT status code. * @param pLnState The line number program state. * @param pCursor The cursor. Log2((
"DW Special Opcode %#04x: uLine + %d => %u; uAddress + %#llx => %#llx; idxOp + %#llx => %#llx\n",
Log2((
"DW_LNS_advance_pc\n"));
Log2((
"DW_LNS_set_column\n"));
Log2((
"DW_LNS_negate_stmt\n"));
Log2((
"DW_LNS_set_basic_block\n"));
Log2((
"DW_LNS_const_add_pc\n"));
Log2((
"DW_LNS_fixed_advance_pc\n"));
Log2((
"DW_LNS_set_prologue_end\n"));
Log2((
"DW_LNS_set_epilogue_begin\n"));
/* The instruction has a length prefix. */ /* Get the opcode and deal with it if we know it. */ #
if 0
/* No need for this, I think. */ Log2((
"DW_LNE_end_sequence\n"));
Log2((
"rtDwarfLine_RunProgram: Unknown extended opcode %#x, length %#x\n",
bOpCode,
cbInstr));
/* Advance the cursor to the end of the instruction . */ * Check the status before looping. * Reads the include directories for a line number unit. * @returns IPRT status code * @param pLnState The line number program state. * @param pCursor The cursor. * Reads the include directories for a line number unit. * @returns IPRT status code * @param pLnState The line number program state. * @param pCursor The cursor. const char *
psz =
"";
/* The zeroth is the unit dir. */ * Explodes the line number table for a compilation unit. * @returns IPRT status code * @param pThis The DWARF instance. * @param pCursor The cursor to read the line number information Log2((
"DWARF Line number header:\n" " offFirstOpcode %#llx\n" * Explodes the line number table. * The line numbers are insered into the debug info container. * @returns IPRT status code * @param pThis The DWARF instance. * Deals with a cache miss in rtDwarfAbbrev_Lookup. * @returns Pointer to abbreviation cache entry (read only). May be rendered * invalid by subsequent calls to this function. * @param pThis The DWARF instance. * @param uCode The abbreviation code to lookup. * There is no entry with code zero. * Resize the cache array if the code is considered cachable. * Walk the abbreviations till we find the desired code. * Search for the entry and fill the cache while doing so. /* Skip the specification. */ /* Done? (Maximize cache filling.) */ * Search for the entry with the desired code, no cache filling. /* Do we have a match? */ /* Skip the specification. */ * Looks up an abbreviation. * @returns Pointer to abbreviation cache entry (read only). May be rendered * invalid by subsequent calls to this function. * @param pThis The DWARF instance. * @param uCode The abbreviation code to lookup. * Sets the abbreviation offset of the current unit. * This will flush the cached abbreviation entries if the offset differs from * @param pThis The DWARF instance. * @param offAbbrev The offset into the abbreviation section. * DWARF debug_info parser * DWARF debug_info parser * DWARF debug_info parser * Read the compilation unit header. * Set up the abbreviation cache and store the native address size in the cursor. /** @todo The fun starts again here. */ * Check status codes before continuing. * The symbols are insered into the debug info container. * @returns IPRT status code * @param pThis The DWARF instance. * DWARF Debug module implementation. * DWARF Debug module implementation. * DWARF Debug module implementation. /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */ /** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */ /** @callback_method_impl{FNRTLDRENUMDBG} */ * Skip stuff we can't handle. * Must have a part name starting with debug_ and possibly prefixed by dots * Figure out which part we're talking about. /** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */ * DWARF is only supported when part of an image. * Enumerate the debug info in the module, looking for DWARF bits. * Extract / explode the data we want (symbols and line numbers) * storing them in a container module. * Free the cached abbreviations and unload all sections. /** Virtual function table for the DWARF debug info reader. */