void InitDebugLine( dw_client cli, const char *source_filename, char *inc_list, unsigned inc_list_len ) { stmt_prologue prol = { 0, DWARF_IMPL_VERSION, sizeof( stmt_prologue ) - offsetof( stmt_prologue, minimum_instruction_length ), DW_MIN_INSTR_LENGTH, 0, DWLINE_BASE, DWLINE_RANGE, DWLINE_OPCODE_BASE, { /* LEB128 args - Instruction op-code */ 0, /* DW_LNS_copy */ 1, /* DW_LNS_advance */ 1, /* DW_LNS_advance_line */ 1, /* DW_LNS_set_file */ 1, /* DW_LNS_set_column */ 0, /* DW_LNS_negate_stmt */ 0, /* DW_LNS_set_basic_block */ 0, /* DW_LNS_const_add_pc */ 0 /* DW_LNS_fixed_advance_pc */ /* // GNU sets the last entry to 1. This is (maybe?) incorrect as the DW_LNS_fixed_advance_pc // opcode has a fixed uhalf (uint_16)argument, not a (U)LEB128 argument. */ } }; static uint_8 const terminators[] = {0,0}; prol.prologue_length += inc_list_len + 2; // +2 for 2 list terminators cli->debug_line.files = NULL; cli->debug_line.addr = 0; cli->debug_line.line = 1; cli->debug_line.column = 0; cli->debug_line.is_stmt = 0; cli->debug_line.end_sequence = 0; /* write the prologue */ CLIWrite( DW_DEBUG_LINE, (char*)&prol, sizeof( prol ) ); if( inc_list != 0 ) { // write the include list CLIWrite( DW_DEBUG_LINE, inc_list, inc_list_len ); } CLIWrite( DW_DEBUG_LINE, terminators, sizeof(terminators) ); /* and put out the source filename */ GetFileNumber( cli, source_filename ); }
static void writeFileName( dw_client cli, const char *name, size_t len ) // len of name including terminator { uint_8 buf[1 + MAX_LEB128 + 1 + _MAX_PATH + 1 + MAX_LEB128 * 3]; uint_8 attribBuf[MAX_LEB128]; uint_8 *end; int bufSize = 0; buf[0] = 0; // identifies extended opcode bufSize = 2+len; // size of sub-opcode, name+terminator, & path size // find out size of file time/size leb128's: end = ULEB128( attribBuf, 0 ); //NYI: replace 0 with time/date stamp of file bufSize += end-attribBuf; // add on size of time stamp val end = ULEB128( attribBuf, 0 ); //NYI: replace 0 with file size bufSize += end-attribBuf; // add on size of file size val end = ULEB128(buf+1,bufSize); // write the opcode size *end = DW_LNE_define_file; // write in the sub-opcode end++; end = (uint_8 *)strncpy( (char *)end, name, len ); // write the filename end += len; end = ULEB128( end, 0 ); // not using a path index // write the file attributes end = ULEB128( end, 0 ); // NYI: replace 0 with time/date stamp of file end = ULEB128( end, 0 ); // NYI: replace 0 with size file CLIWrite( DW_DEBUG_LINE, buf, end-buf ); }
void InfoBytes( dw_client cli, const void * buf, dw_size_t size ) { CLIWrite( DW_DEBUG_INFO, buf, size ); }
void DWENTRY DWPubname( dw_client cli, dw_handle hdl, const char * name ) { HandleReference( cli, hdl, DW_DEBUG_PUBNAMES ); CLIWrite( DW_DEBUG_PUBNAMES, name, strlen( name ) + 1 ); }
void FiniDebugLine( dw_client cli ) { char buf[ sizeof( uint_32 ) ]; long size; buf[ 0 ] = 0; buf[ 1 ] = 1; buf[ 2 ] = DW_LNE_end_sequence; CLIWrite( DW_DEBUG_LINE, buf, 3 ); size = CLITell( DW_DEBUG_LINE ) - sizeof( uint_32 ) - cli->section_base[ DW_DEBUG_LINE ]; WriteU32( buf, size ); CLISeek( DW_DEBUG_LINE, cli->section_base[ DW_DEBUG_LINE ], DW_SEEK_SET ); CLIWrite( DW_DEBUG_LINE, buf, sizeof(uint_32) ); CLISeek( DW_DEBUG_LINE, 0, DW_SEEK_END ); FreeChain( cli, cli->debug_line.files ); }
void Info16( dw_client cli, uint_16 value ) { char buf[ sizeof( uint_16 ) ]; WriteU16( buf, value ); CLIWrite( DW_DEBUG_INFO, &buf, sizeof( buf ) ); }
void Info32( dw_client cli, uint_32 value ) { char buf[ sizeof( uint_32 ) ]; WriteU32( buf, value ); CLIWrite( DW_DEBUG_INFO, &buf, sizeof( buf ) ); }
void DWENTRY DWLineNum( dw_client cli, uint info, dw_linenum line_num, dw_column column, dw_addr_offset addr ) { uint_8 buf[ 3 + 2 * MAX_LEB128 ]; uint_8 *end; unsigned size; /* set the basic_block register properly */ if( info & DW_LN_BLK ) { buf[ 0 ] = DW_LNS_set_basic_block; CLIWrite( DW_DEBUG_LINE, buf, 1 ); } /* set the is_stmt register properly */ if( info & DW_LN_STMT ) { if( !cli->debug_line.is_stmt ) { cli->debug_line.is_stmt = 1; buf[ 0 ] = DW_LNS_negate_stmt; CLIWrite( DW_DEBUG_LINE, buf, 1 ); } } else if( cli->debug_line.is_stmt ) { cli->debug_line.is_stmt = 0; buf[ 0 ] = DW_LNS_negate_stmt; CLIWrite( DW_DEBUG_LINE, buf, 1 ); } if( column != cli->debug_line.column ) { cli->debug_line.column = column; buf[ 0 ] = DW_LNS_set_column; end = LEB128( buf + 1, column ); CLIWrite( DW_DEBUG_LINE, buf, end - buf ); } size = DWLineGen( line_num - cli->debug_line.line, addr - cli->debug_line.addr, buf ); CLIWrite( DW_DEBUG_LINE, buf, size ); cli->debug_line.addr = addr; cli->debug_line.line = line_num; }
static void CLIZeroWrite( dw_sectnum sect, uint size ) { /*************************************************/ char *btmp; btmp = FMemAlloc( size+1 ); memset( btmp, 0, size ); CLIWrite( sect, btmp, size ); FMemFree( btmp ); }
void FiniDebugPubnames( dw_client cli ) { static char const zeros[ sizeof( uint_32 ) ]; char buf[ sizeof( debug_ref ) ]; debug_ref offset; /* write the set terminator */ CLIWrite( DW_DEBUG_PUBNAMES, zeros, sizeof( uint_32 ) ); /* backpatch the section length */ offset = CLITell( DW_DEBUG_PUBNAMES ) - cli->section_base[ DW_DEBUG_PUBNAMES ] - sizeof( debug_ref ); WriteRef( buf, offset ); CLISeek( DW_DEBUG_PUBNAMES, cli->section_base[ DW_DEBUG_PUBNAMES ], DW_SEEK_SET ); CLIWrite( DW_DEBUG_PUBNAMES, buf, sizeof( debug_ref ) ); CLISeek( DW_DEBUG_PUBNAMES, 0, DW_SEEK_END ); }
void InfoULEB128( dw_client cli, dw_uconst value ) { uint_8 buf[ MAX_LEB128 ]; uint_8 *end; end = ULEB128( buf, value ); CLIWrite( DW_DEBUG_INFO, buf, end - buf ); }
void InitDebugPubnames( dw_client cli ) { static uint_16 const version = 2; /* write the set header */ CLISeek( DW_DEBUG_PUBNAMES, sizeof( uint_32 ), DW_SEEK_CUR ); CLIWrite( DW_DEBUG_PUBNAMES, &version, sizeof( version ) ); CLIReloc3( DW_DEBUG_PUBNAMES, DW_W_SECTION_POS, DW_DEBUG_INFO ); CLIReloc2( DW_DEBUG_PUBNAMES, DW_W_UNIT_SIZE ); }
void InfoPatch( dw_client cli, debug_ref offs, const void * value, dw_size_t len ) { CLISeek( DW_DEBUG_INFO, offs + cli->section_base[ DW_DEBUG_INFO ], DW_SEEK_SET ); CLIWrite( DW_DEBUG_INFO, value, len ); CLISeek( DW_DEBUG_INFO, 0, DW_SEEK_END ); }
void DWENTRY DWSetFile( dw_client cli, const char *filename ) { uint_8 buf[ 1 + MAX_LEB128 ]; uint_8 *end; _Validate( filename != NULL ); buf[0] = DW_LNS_set_file; end = LEB128( buf + 1, GetFileNumber( cli, filename ) ); CLIWrite( DW_DEBUG_LINE, buf, end - buf ); }
void DWLineAddr( dw_client cli, dw_sym_handle sym, dw_addr_offset addr ) { uint_8 buf[1 + MAX_LEB128 + sizeof( dw_targ_addr )]; uint_8 *end; buf[ 0 ] = 0; //extended end = ULEB128(buf+1, 1+cli->offset_size ); // write the opcode size *end = DW_LNE_set_address; ++end; CLIWrite( DW_DEBUG_LINE, buf, end-buf ); CLIReloc3( DW_DEBUG_LINE, DW_W_LABEL, sym ); cli->debug_line.addr = addr; }
void DWLineSeg( dw_client cli, dw_sym_handle sym ) { uint_8 buf[1 + MAX_LEB128 + sizeof( dw_targ_addr )]; uint_8 *end; if( cli->segment_size != 0 ) { buf[ 0 ] = 0; //extended end = ULEB128(buf+1, 1+cli->segment_size ); // write the opcode size *end = DW_LNE_set_segment; ++end; CLIWrite( DW_DEBUG_LINE, buf, end-buf ); CLIReloc3( DW_DEBUG_LINE, DW_W_LABEL_SEG, sym ); } }
void FiniDebugInfo( dw_client cli ) { char buf[ sizeof( uint_32 ) ]; long size; /* patch in the length of the .debug_info section */ size = CLITell( DW_DEBUG_INFO ); size -= sizeof( uint_32 ); size -= cli->section_base[ DW_DEBUG_INFO ]; CLISeek( DW_DEBUG_INFO, cli->section_base[ DW_DEBUG_INFO ], DW_SEEK_SET ); WriteU32( buf, size ); CLIWrite( DW_DEBUG_INFO, buf, sizeof( uint_32 ) ); CLISeek( DW_DEBUG_INFO, 0, DW_SEEK_END ); }
static void CLIReloc( dw_sectnum sect, dw_relocs reloc_type, ... ) { /******************************************************/ static char zeros[] = { 0, 0 }; // dw_sym_handle sym; uint section; va_list args; unsigned_32 u32_data; va_start( args, reloc_type ); switch( reloc_type ) { case DW_W_LOW_PC: case DW_W_LABEL: case DW_W_DEFAULT_FUNCTION: case DW_W_ARANGE_ADDR: u32_data = 0; // NOTE: assumes little-endian byte order CLIWrite( sect, &u32_data, sizeof( int ) ); break; case DW_W_HIGH_PC: u32_data = 1; // NOTE: assumes little-endian byte order CLIWrite( sect, &u32_data, sizeof( int ) ); break; case DW_W_UNIT_SIZE: u32_data = 1; // NOTE: assumes little-endian byte order CLIWrite( sect, &u32_data, sizeof( uint_32 ) ); break; case DW_W_SECTION_POS: section = va_arg( args, uint ); CLIWrite( sect, &Sections[ section ].cur_offset, sizeof( uint_32 ) ); break; case DW_W_STATIC: // sym = va_arg( args, dw_sym_handle ); u32_data = 0; CLIWrite( sect, &u32_data, sizeof( uint_32 ) ); CLIWrite( sect, zeros, sizeof( zeros ) ); break; case DW_W_SEGMENT: CLIWrite( sect, zeros, sizeof( zeros ) ); break; default: abort(); break; } }
void CLIReloc( dw_sectnum sect, dw_relocs reloc_type, ... ) { static char zeros[] = { 0, 0 }; dw_sym_handle sym; uint section; va_list args; va_start( args, reloc_type ); switch( reloc_type ) { case DW_W_LOW_PC: case DW_W_HIGH_PC: case DW_W_LABEL: case DW_W_DEFAULT_FUNCTION: case DW_W_ARANGE_ADDR: CLIWrite( sect, &RelocValues[ reloc_type ], sizeof( uint_32 ) ); CLIWrite( sect, zeros, sizeof( zeros ) ); break; case DW_W_UNIT_SIZE: CLIWrite( sect, &RelocValues[ reloc_type ], sizeof( uint_32 ) ); break; case DW_W_SECTION_POS: section = va_arg( args, uint ); CLIWrite( sect, &Sections[ section ].cur_offset, sizeof( uint_32 ) ); break; case DW_W_STATIC: sym = va_arg( args, dw_sym_handle ); CLIWrite( sect, &SymHandles[ sym ], sizeof( uint_32 ) ); CLIWrite( sect, zeros, sizeof( zeros ) ); break; case DW_W_SEGMENT: sym = va_arg( args, dw_sym_handle ); CLIWrite( sect, zeros, sizeof( zeros ) ); break; default: abort(); break; } }
void Info8( dw_client cli, uint_8 value ) { CLIWrite( DW_DEBUG_INFO, &value, sizeof( uint_8 ) ); }