Пример #1
0
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 );
}
Пример #2
0
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 );
}
Пример #3
0
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;
}
Пример #4
0
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 );
    }
}
Пример #5
0
void emitEncodings(
    FILE *                      fp )
{
/*
    The plan is to take the above table and compress it into a smaller
    form.  The first obvious thing is to do the ULEB128 encodings now
    since they are compile-time constant, and much smaller.
*/
    uint                u;
    uint_8              *end;
    uint_8              *p;
    uint_32 const       *data;

    topOfEncoding = 0;
    for( u = 0; u < AB_MAX; ++u ) {
        /*
            Determine what the sequence of bytes is for this abbreviation
        */
        end = tempEncoding;
        for( data = abbrevInfo[u].data; *data; ++data ) {
            end = ULEB128( end, *data );
        }
        abbrevExtra[u].data_len = end - tempEncoding;
        abbrevExtra[u].data_offset = addToEncoding( end - tempEncoding );
    }

    fprintf( fp, "\nstatic const uint_8 encodings[] = {\n    /* 0x00 */ " );
    end = encodingBuf + topOfEncoding;
    p = encodingBuf;
    for(;;) {
        fprintf( fp, "0x%02x", *p );
        ++p;
        if( p == end ) break;
        fprintf( fp, "," );
        if( ( p - encodingBuf ) % 8 == 0 ) {
            fprintf( fp, "\n    /* 0x%02x */ ", (unsigned)( p - encodingBuf ) );
        }
    }
    fprintf( fp, "\n};\n\n" );
}
void DwarfFrameManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
	CiePtrEncodingMap ptrEncodingMap;
	CieAugmentationMap augmentationMap;
	size_t encoded_ptr_size = ENCODED_POINTER_SIZE;
	size_t bytes_read;
	Dwarf_Byte_Ptr start = aStart;
	Dwarf_Byte_Ptr section_start = start;
	Dwarf_Byte_Ptr end = aEnd;
	while (start < end) {
		unsigned char *augmentation_data = NULL;
		unsigned long augmentation_data_len = 0;
		size_t offset_size;
		size_t initial_length_size;

		Dwarf_Byte_Ptr saved_start = start;
		Dwarf_Word length = READ_UNALIGNED4(start); 
		start += 4;

		if (length == 0){ // ZERO terminator - shouldn't see this
			continue;
		}	

		if (length >= 0xfffffff0u) {
			cerr << "Error: 64 bit DWARF not supported\n";
			exit(EXIT_FAILURE);
		} else {	
			offset_size = 4;
			initial_length_size = 4;
		}

		Dwarf_Byte_Ptr block_end = saved_start + length + initial_length_size;
		if (block_end > end) {
			cerr << "Warning: Invalid length " << length << " in FDE at 0x" 
				<< (unsigned long)(saved_start - section_start) << " in file " << aPair.iXIPFileDetails.iElfFile << "\n";
			block_end = end;
		}	
		Dwarf_Word cie_id = READ_UNALIGNED4(start); 
		if (cie_id != (Dwarf_Word)DW_CIE_ID)
			WRITE_UNALIGNED4(start, cie_id + GetSectionOffset(aPair.iXIPFileDetails.iElfFile));
		start += offset_size;

		if (cie_id == (Dwarf_Word)DW_CIE_ID) {
			Dwarf_Ubyte version = *start++;

			char * augmentation = (char *) start;
			augmentation_data = NULL;
			start = (Dwarf_Byte_Ptr) strchr ((char *) start, '\0') + 1;

			if (augmentation[0] == 'z'){
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);

				if (version == 1){
					// fc->ra = GET (1);
					start++;
				} else {
					// fc->ra = LEB ();
					ULEB128(start, bytes_read);
				}
				augmentation_data_len = ULEB128(start, bytes_read);
				augmentation_data = start;
				augmentationMap[saved_start] = augmentation_data_len;
				start += augmentation_data_len;
			} else if (strcmp (augmentation, "eh") == 0){
				//start += eh_addr_size;
				start += 4;
				// fc->code_factor = LEB ();
				// fc->data_factor = SLEB ();
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);
				if (version == 1){
					//c->ra = GET (1);
					start++;
				} else {
					// fc->ra = LEB ();
					ULEB128(start, bytes_read);
				}
			} else {
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);

				if (version == 1){
					// fc->ra = GET (1);
					start++;
				} else {
					// fc->ra = LEB ();
					ULEB128(start, bytes_read);
				}
			}

			if (augmentation_data_len){
				unsigned char *p, *q;
				p = (unsigned char *) augmentation + 1;
				q = augmentation_data;
				Dwarf_Ubyte encoding = 0;
				while (1){
					if (*p == 'L')
						q++;
					else if (*p == 'P')
						q += 1 + SizeOfEncodedValue(*q);
					else if (*p == 'R')
						encoding = *q++;
					else
						break;
					p++;
				}
				if (encoding)
					ptrEncodingMap[saved_start] = encoding;
			}
	  
		} else {
			Dwarf_Byte_Ptr look_for = section_start + cie_id;
			Dwarf_Ubyte encoding = 0;
			CiePtrEncodingMap::iterator iE = ptrEncodingMap.find(look_for);
			if (iE != ptrEncodingMap.end()){
				encoding = iE->second;
				encoded_ptr_size = SizeOfEncodedValue(encoding);
			}
			if ((encoding & 0x70) != DW_EH_PE_pcrel){
				// do the nasty
				LinearAddr addr = GetValue(start, encoded_ptr_size);
				LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
				if (ValueFitsSize(relocatedAddr, encoded_ptr_size)){
					WriteValue(start, relocatedAddr, encoded_ptr_size);
				} else {
					cerr << "Warning: relocated addresses in " << GetSectionName().c_str() 
					<< " section of " << aPair.iXIPFileDetails.iElfFile.c_str() 
					<< " too large for encoding. Backtraces may be misleading.\n";
					}
			}
			start += encoded_ptr_size;
			// skip the range size
			start += encoded_ptr_size;

			CieAugmentationMap::iterator iP =  augmentationMap.find(look_for);
			if (iP != augmentationMap.end()){
				ULEB128(start, bytes_read);
				start += bytes_read;
			}
		}
		
		Dwarf_Word tmp = 0;
		while (start < block_end){
			unsigned op, opa;
			op = *start++;
			opa = op & 0x3f;
			if (op & 0xc0)
				op &= 0xc0;
			switch (op){
			case DW_CFA_advance_loc:
				break;
			case DW_CFA_offset:
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_restore:
				break;
			case DW_CFA_set_loc:
				start += encoded_ptr_size;
				break;
			case DW_CFA_advance_loc1:
				start += 1;
				break;
			case DW_CFA_advance_loc2:
				start += 2;
				break;
			case DW_CFA_advance_loc4:
				start += 4;
				break;
			case DW_CFA_offset_extended:
			case DW_CFA_val_offset:
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_restore_extended:
			case DW_CFA_undefined:
			case DW_CFA_same_value:
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_register:
			case DW_CFA_def_cfa:
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_def_cfa_register:
			case DW_CFA_def_cfa_offset:
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_def_cfa_expression:
				tmp = ULEB128(start, bytes_read);
				EditLocationExpression (start, encoded_ptr_size, tmp, aPair);
				start += tmp;
				break;
			case DW_CFA_expression: 
			case DW_CFA_val_expression: 
				ULEB128(start, bytes_read);
				tmp = ULEB128(start, bytes_read);
				EditLocationExpression (start, encoded_ptr_size, tmp, aPair);
				start += tmp;
				break;
#ifndef DW_CFA_offset_extended_sf
// seems to be type in dwarf.h
#define DW_CFA_offset_extended_sf 0x11
				//DW_CFA_cfa_offset_extended_sf
#endif
			case DW_CFA_offset_extended_sf:
			case DW_CFA_val_offset_sf:
			case DW_CFA_def_cfa_sf:
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_def_cfa_offset_sf:
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_MIPS_advance_loc8:
				start += 8;
				break;
			case DW_CFA_GNU_args_size:
				ULEB128(start, bytes_read);
				break;
			case DW_CFA_GNU_negative_offset_extended:
				ULEB128(start, bytes_read);
				ULEB128(start, bytes_read);
				break;
			default:
				break;
			}
		}
	}

}