static void AddTables ( FILE * df ) { ASSERT(df); //-------------------------------------------------- #if 0 // [[2do]] not needed yet print_section(df,sep2,"Region Info"); char ch; for ( ch = 'A'; ch <= 'Z'; ch++ ) { const RegionInfo_t * reg = GetRegionInfo(ch); fprintf(df,"#:def_tab(\"region\",'%c',%u,%u,\"%s\",\"%s\")\n", ch, reg->reg, reg->mandatory, reg->name4, reg->name ); } const RegionInfo_t * reg = GetRegionInfo(0); fprintf(df,"#:def_tab(\"region\",'',%2u,%u,\"%s\",\"%s\")\n", reg->reg, reg->mandatory, reg->name4, reg->name ); #endif //-------------------------------------------------- }
void CountryInfoGetter::GetRegionInfo(m2::PointD const & pt, CountryInfo & info) const { GetByPoint doGet(*this, pt); ForEachCountry(pt, doGet); if (doGet.m_res != -1) GetRegionInfo(m_countries[doGet.m_res].m_name, info); }
void InitializeBacktrace() { static bool bInitialized = false; if( bInitialized ) return; vm_prot_t protection; if( !GetRegionInfo(mach_task_self(), __builtin_frame_address(0), g_StackPointer, protection) || protection != PROT_RW ) { g_StackPointer = 0; } bInitialized = true; }
void CountryInfoGetter::GetRegionInfo(m2::PointD const & pt, CountryInfo & info) const { IdType const id = FindFirstCountry(pt); if (id != kInvalidId) GetRegionInfo(m_countries[id].m_name, info); }
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { InitializeBacktrace(); if( g_StackPointer == 0 ) { buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE; buf[1] = NULL; return; } BacktraceContext CurrentCtx; if( ctx == NULL ) { ctx = &CurrentCtx; CurrentCtx.ip = NULL; CurrentCtx.bp = __builtin_frame_address(0); CurrentCtx.sp = __builtin_frame_address(0); } mach_port_t self = mach_task_self(); vm_address_t stackPointer = 0; vm_prot_t protection = 0; vm_address_t start = 0; size_t i = 0; if( i < size-1 && ctx->ip ) buf[i++] = ctx->ip; if( GetRegionInfo(self, ctx->sp, stackPointer, protection) && protection == (VM_PROT_READ|VM_PROT_WRITE) ) { const void *p = *(const void **)ctx->sp; if( GetRegionInfo(self, p, start, protection) && (protection & (VM_PROT_READ|VM_PROT_EXECUTE)) == (VM_PROT_READ|VM_PROT_EXECUTE) && PointsToValidCall(start, p) && i < size-1 ) { buf[i++] = p; } } GetRegionInfo( self, ctx->sp, stackPointer, protection ); if( protection != PROT_RW ) { /* There isn't much we can do if this is the case. The stack should be read/write * and since it isn't, give up. */ buf[i] = NULL; return; } const Frame *frame = (Frame *)ctx->sp; while( i < size-1 ) { // Make sure this is on the stack if( !GetRegionInfo(self, frame, start, protection) || protection != PROT_RW ) break; if( (start != g_StackPointer && start != stackPointer) || uintptr_t(frame)-uintptr_t(start) < sizeof(Frame) ) break; /* The stack pointer is always 16 byte aligned _before_ the call. Thus a valid frame * should look like the follwoing. * | | * | Caller's frame | * -------------------- 16 byte boundary * | Linkage | This is return_address * - - - - - - - - - - * | Saved %ebp | This is link * - - - - - - - - - - * | Rest of | * | Callee's frame | * * Therefore, frame + 8 should be on a 16 byte boundary, the frame link should be * at a higher address, the link should be on the stack and it should be RW. The * return address should be EXE and point to a valid call (well, just after). */ if( (((uintptr_t)frame+8) & 0xF) != 0 ||// boundary frame->link <= frame || // the frame link goes up !GetRegionInfo(self, frame->link, start, protection) || (start != g_StackPointer && start != stackPointer) || // the link is on the stack protection != PROT_RW || // RW !GetRegionInfo(self, frame->return_address, start, protection) || protection != PROT_EXE || // EXE !PointsToValidCall(start, frame->return_address) )// follows a CALL { /* This is not a valid frame but we might be in code compiled with * -fomit-frame-pointer so look at each address on the stack that is * 4 bytes below a 16 byte boundary. */ if( (((uintptr_t)frame+4) & 0xF) == 0 ) { void *p = *(void **)frame; if( GetRegionInfo(self, p, start, protection) && protection == PROT_EXE && PointsToValidCall(start, p) ) { buf[i++] = p; } } frame = (Frame *)(intptr_t(frame)+4); continue; } // Valid. buf[i++] = frame->return_address; frame = frame->link; } buf[i] = NULL; }