SF Bug 1284 - QEMU has faulty instruction emulation for VMOV (between two ARM core registers and two single-precision registers)
/** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).* All rights reserved.** This program is free software: you can redistribute it and/or modify* it under the terms of the GNU Lesser General Public License as published by* the Free Software Foundation, either version 3 of the License, or* (at your option) any later version.** This program 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 Lesser General Public License for more details.* * You should have received a copy of the GNU Lesser General Public License* along with this program. If not, see <http://www.gnu.org/licenses/>.*/#include <iostream>#include "dwarfmanager.h"#include "inputfile.h"const string DwarfAbbrevManager::iAbbrevSectionName(".debug_abbrev");void InfoContext::SetAbbrevOffset(size_t offset){ if (!iContextValid){ cerr << "Error: runtime error - SetAbbrevOffset called on invalid InfoContext\n"; exit(EXIT_FAILURE); } if (iAbbrevOffset == offset) return; // Save current entry (in particular the cursor value if (iAbbrevOffset != 0xffffffff){ AbbrevOffsetMap::iterator old = iMap.find(iAbbrevOffset); if (old != iMap.end()) old->second.iCursor = iAbbrevMapEntry.iCursor; else iMap[iAbbrevOffset] = iAbbrevMapEntry; } AbbrevOffsetMap::iterator i = iMap.find(offset); if (i != iMap.end()){ iAbbrevMapEntry = i->second; } else { AbbrevMap * newMap = new AbbrevMap; new (&iAbbrevMapEntry) AbbrevMapEntry(iSectionStart + offset, newMap); iMap[offset] = iAbbrevMapEntry; } iAbbrevOffset = offset;}DebugAbbrev & InfoContext::GetAbbrev(Dwarf_Word aCode){ AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode); if (i != iAbbrevMapEntry.iMap->end()){ return i->second; } else { return FindAbbrev(aCode); }}DebugAbbrev & InfoContext::FindAbbrev(Dwarf_Word aCode){ // retrieve cursor for where we've scanned so far. Dwarf_Byte_Ptr p = iAbbrevMapEntry.iCursor; // NB. error if we don't find the code before section end Dwarf_Byte_Ptr lim = iSectionEnd; bool error = false; bool found = false; size_t leb128_length; while (!found && (p < lim)){#define CHECK_ABBREV_LIM(p,l,e) { if ((p)>(l)){ e = true; break;} }#define CHECK_DECODE_ULEB128(v,p,n,l,e) \ DECODE_ULEB128(v,p,n)\ CHECK_ABBREV_LIM(p,l,e); size_t count = 0; //CHECK_DECODE_ULEB128(abbrev_code,p,leb128_length,lim, error); Dwarf_Word abbrev_code = DwarfSectionManager::DecodeUnsignedLeb128(p, leb128_length); p += leb128_length; if (p>lim){ error = true; break; } // Might as well error here since either we've found the NULL abbrev if (abbrev_code == 0) { DebugAbbrev abbr(0, 0, 0, NULL, NULL); (*iAbbrevMapEntry.iMap)[0] = abbr; if (aCode == 0) // ??? why would it found = true; } CHECK_DECODE_ULEB128(tag,p,leb128_length,lim, error); // don't care about 'has child' p++; CHECK_ABBREV_LIM(p,lim,error); Dwarf_Byte_Ptr raw_attr_ptr = p; Dwarf_Word attr; Dwarf_Word attr_form; do { CHECK_DECODE_ULEB128(a,p,leb128_length,lim, error); attr = a; CHECK_DECODE_ULEB128(f,p,leb128_length,lim, error); attr_form = f; if (attr != 0) count++; } while (attr != 0 || attr_form != 0); DebugAbbrevAttrForm * list = new DebugAbbrevAttrForm[count]; Dwarf_Byte_Ptr q=raw_attr_ptr; for (size_t i=0 ; i < count ; i++){ list[i].iAttr = ULEB128(q,leb128_length); list[i].iForm = ULEB128(q,leb128_length); } DebugAbbrev abbr(abbrev_code, tag, count, raw_attr_ptr, list); (*iAbbrevMapEntry.iMap)[abbrev_code] = abbr; if (abbrev_code == aCode) found = true; } if (error){ cerr << "Error: corrupt .debug_abbrev section\n"; exit(EXIT_FAILURE); } if (!found){ cerr << "Error: abbrev code not found in .debug_abbrev section\n"; exit(EXIT_FAILURE); } // record where we scanned to iAbbrevMapEntry.iCursor = p; // get the AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode); if (i == iAbbrevMapEntry.iMap->end()){ cerr << "Error: Runtime error processing .debug_abbrev section\n"; exit(EXIT_FAILURE); } return i->second;}void DwarfAbbrevManager::StartContext(PathName & aName){ Dwarf_Byte_Ptr section = GetSection(aName); iInfoContext.Init(section, section + GetSectionSize(aName), GetSectionOffset(aName));}void DwarfAbbrevManager::EndContext(){ iInfoContext.Reset();}void DwarfAbbrevManager::SetContextAbbrevOffset(Uint32 offset){ iInfoContext.SetAbbrevOffset(offset);}size_t DwarfAbbrevManager::GetContextSectionOffset(){ return iInfoContext.GetSectionOffset();}DebugAbbrev & DwarfAbbrevManager::GetAbbrev(Dwarf_Word aCode){ return iInfoContext.GetAbbrev(aCode);}