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 ); }
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 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 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; } } } }