コード例 #1
0
ファイル: sdhci.c プロジェクト: 2asoft/freebsd
static void
sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock)
{
	uint32_t clk_base;
	uint32_t clk_sel;
	uint32_t res;
	uint16_t clk;
	uint16_t div;
	int timeout;

	if (clock == slot->clock)
		return;
	slot->clock = clock;

	/* Turn off the clock. */
	clk = RD2(slot, SDHCI_CLOCK_CONTROL);
	WR2(slot, SDHCI_CLOCK_CONTROL, clk & ~SDHCI_CLOCK_CARD_EN);
	/* If no clock requested - left it so. */
	if (clock == 0)
		return;
	
	/* Determine the clock base frequency */
	clk_base = slot->max_clk;
	if (slot->quirks & SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC) {
		clk_sel = RD2(slot, BCM577XX_HOST_CONTROL) & BCM577XX_CTRL_CLKSEL_MASK;

		/* Select clock source appropriate for the requested frequency. */
		if ((clk_base / BCM577XX_DEFAULT_MAX_DIVIDER) > clock) {
			clk_base = BCM577XX_ALT_CLOCK_BASE;
			clk_sel |= (BCM577XX_CTRL_CLKSEL_64MHZ << BCM577XX_CTRL_CLKSEL_SHIFT);
		} else {
			clk_sel |= (BCM577XX_CTRL_CLKSEL_DEFAULT << BCM577XX_CTRL_CLKSEL_SHIFT);
		}
		
		WR2(slot, BCM577XX_HOST_CONTROL, clk_sel);
	}

	/* Recalculate timeout clock frequency based on the new sd clock. */
	if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
		slot->timeout_clk = slot->clock / 1000;

	if (slot->version < SDHCI_SPEC_300) {
		/* Looking for highest freq <= clock. */
		res = clk_base;
		for (div = 1; div < SDHCI_200_MAX_DIVIDER; div <<= 1) {
			if (res <= clock)
				break;
			res >>= 1;
		}
		/* Divider 1:1 is 0x00, 2:1 is 0x01, 256:1 is 0x80 ... */
		div >>= 1;
	}
コード例 #2
0
ファイル: imx_wdog.c プロジェクト: 2asoft/freebsd
static void
imx_watchdog(void *arg, u_int cmd, int *error)
{
	struct imx_wdog_softc *sc;
	uint16_t reg;
	u_int timeout;

	sc = arg;
	mtx_lock(&sc->sc_mtx);
	if (cmd == 0) {
		if (bootverbose)
			device_printf(sc->sc_dev, "Can not be disabled.\n");
		*error = EOPNOTSUPP;
	} else {
		timeout = (u_int)((1ULL << (cmd & WD_INTERVAL)) / 1000000000U);
		if (timeout > 1 && timeout < 128) {
			if (timeout != sc->sc_timeout) {
				sc->sc_timeout = timeout;
				reg = RD2(sc, WDOG_CR_REG);
				reg &= ~WDOG_CR_WT_MASK;
				reg |= (timeout << (WDOG_CR_WT_SHIFT + 1)) &
				    WDOG_CR_WT_MASK;
				WR2(sc, WDOG_CR_REG, reg | WDOG_CR_WDE);
			}
			/* Refresh counter */
			WR2(sc, WDOG_SR_REG, WDOG_SR_STEP1);
			WR2(sc, WDOG_SR_REG, WDOG_SR_STEP2);
			*error = 0;
		}
	}
	mtx_unlock(&sc->sc_mtx);
}
コード例 #3
0
static void
sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock)
{
	uint32_t res;
	uint16_t clk;
	uint16_t div;
	int timeout;

	if (clock == slot->clock)
		return;
	slot->clock = clock;

	/* Turn off the clock. */
	clk = RD2(slot, SDHCI_CLOCK_CONTROL);
	WR2(slot, SDHCI_CLOCK_CONTROL, clk & ~SDHCI_CLOCK_CARD_EN);
	/* If no clock requested - left it so. */
	if (clock == 0)
		return;

	/* Recalculate timeout clock frequency based on the new sd clock. */
	if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
		slot->timeout_clk = slot->clock / 1000;

	if (slot->version < SDHCI_SPEC_300) {
		/* Looking for highest freq <= clock. */
		res = slot->max_clk;
		for (div = 1; div < SDHCI_200_MAX_DIVIDER; div <<= 1) {
			if (res <= clock)
				break;
			res >>= 1;
		}
		/* Divider 1:1 is 0x00, 2:1 is 0x01, 256:1 is 0x80 ... */
		div >>= 1;
	}
コード例 #4
0
ファイル: sdhci.c プロジェクト: 2asoft/freebsd
static void
sdhci_dumpregs(struct sdhci_slot *slot)
{
	slot_printf(slot,
	    "============== REGISTER DUMP ==============\n");

	slot_printf(slot, "Sys addr: 0x%08x | Version:  0x%08x\n",
	    RD4(slot, SDHCI_DMA_ADDRESS), RD2(slot, SDHCI_HOST_VERSION));
	slot_printf(slot, "Blk size: 0x%08x | Blk cnt:  0x%08x\n",
	    RD2(slot, SDHCI_BLOCK_SIZE), RD2(slot, SDHCI_BLOCK_COUNT));
	slot_printf(slot, "Argument: 0x%08x | Trn mode: 0x%08x\n",
	    RD4(slot, SDHCI_ARGUMENT), RD2(slot, SDHCI_TRANSFER_MODE));
	slot_printf(slot, "Present:  0x%08x | Host ctl: 0x%08x\n",
	    RD4(slot, SDHCI_PRESENT_STATE), RD1(slot, SDHCI_HOST_CONTROL));
	slot_printf(slot, "Power:    0x%08x | Blk gap:  0x%08x\n",
	    RD1(slot, SDHCI_POWER_CONTROL), RD1(slot, SDHCI_BLOCK_GAP_CONTROL));
	slot_printf(slot, "Wake-up:  0x%08x | Clock:    0x%08x\n",
	    RD1(slot, SDHCI_WAKE_UP_CONTROL), RD2(slot, SDHCI_CLOCK_CONTROL));
	slot_printf(slot, "Timeout:  0x%08x | Int stat: 0x%08x\n",
	    RD1(slot, SDHCI_TIMEOUT_CONTROL), RD4(slot, SDHCI_INT_STATUS));
	slot_printf(slot, "Int enab: 0x%08x | Sig enab: 0x%08x\n",
	    RD4(slot, SDHCI_INT_ENABLE), RD4(slot, SDHCI_SIGNAL_ENABLE));
	slot_printf(slot, "AC12 err: 0x%08x | Slot int: 0x%08x\n",
	    RD2(slot, SDHCI_ACMD12_ERR), RD2(slot, SDHCI_SLOT_INT_STATUS));
	slot_printf(slot, "Caps:     0x%08x | Max curr: 0x%08x\n",
	    RD4(slot, SDHCI_CAPABILITIES), RD4(slot, SDHCI_MAX_CURRENT));

	slot_printf(slot,
	    "===========================================\n");
}
コード例 #5
0
ファイル: if_ffec.c プロジェクト: Digital-Chaos/freebsd
static void
ffec_miigasket_setup(struct ffec_softc *sc)
{
	uint32_t ifmode;

	/*
	 * We only need the gasket for MII and RMII connections on certain SoCs.
	 */

	switch (sc->fectype & FECTYPE_MASK)
	{
	case FECTYPE_IMX53:
		break;
	default:
		return;
	}

	switch (sc->phy_conn_type)
	{
	case PHY_CONN_MII:
		ifmode = 0;
		break;
	case PHY_CONN_RMII:
		ifmode = FEC_MIIGSK_CFGR_IF_MODE_RMII;
		break;
	default:
		return;
	}

	/*
	 * Disable the gasket, configure for either MII or RMII, then enable.
	 */

	WR2(sc, FEC_MIIGSK_ENR, 0);
	while (RD2(sc, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
		continue;

	WR2(sc, FEC_MIIGSK_CFGR, ifmode);

	WR2(sc, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN);
	while (!(RD2(sc, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY))
		continue;
}
コード例 #6
0
ファイル: ConeSplitMerge.hpp プロジェクト: Dr15Jones/fastjet
void ConeSplitMerge<Item>::split_merge(std::vector<ProtoJet<Item> >& jcv,
				       float shared_ET_fraction,
				       float pT_min_leading_protojet, float pT_min_second_protojet,
				       int MergeMax, float pT_min_noMergeMax) 
{
  while(!_members.empty()) 
  {
    /*
    {
      std::cout << std::endl;
      std::cout << " ---------------  list of protojets ------------------ " <<std::endl;
      for ( PJMMAP::iterator it = _members.begin();
	    it != _members.end(); ++it)
      {
	std::cout << " pT y phi " << (*it).pT() << " " << (*it).y() << " " << (*it).phi() << " " << (*it).info().seedET() <<  " " << (*it).info().nbMerge() << " " << (*it).info().nbSplit() << std::endl;
      }
      std::cout << " ----------------------------------------------------- " <<std::endl;
    }
    */


    // select highest Et jet
    typename PJMMAP::iterator itmax= _members.begin();
    ProtoJet<Item> imax((*itmax).first);
    const std::list<const Item*>& ilist(imax.LItems());

    _members.erase(itmax);
 
    // does jet share items?
    bool share= false;
    float shared_ET = 0.;
    typename PJMMAP::iterator jtmax;
    typename PJMMAP::iterator jt;
    for(jt = _members.begin(); jt != _members.end(); ++jt) 
    {
      const std::list<const Item*>& jlist((*jt).first.LItems());
      typename std::list<const Item*>::const_iterator tk;
      int count;
      for(tk = ilist.begin(), count = 0; tk != ilist.end(); 
	  ++tk, ++count) 
      {
	typename std::list<const Item*>::const_iterator where= 
	  find(jlist.begin(),jlist.end(),*tk);   
	if(where != jlist.end()) 
	{
	  share= true;
	  shared_ET += (*tk)->pT();
	}
      }
      if(share) 
      {
	jtmax = jt;
	break;
      }
    }
    
    if(!share) {
      // add jet to the final jet list
      jcv.push_back(imax);
      //std::cout << " final jet " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 
    }
    else 
    {
      // find highest Et neighbor
      ProtoJet<Item> jmax((*jtmax).first);

      // drop neighbor
      _members.erase(jtmax);


      //std::cout << " split or merge ? " << imax.pT() << " " << shared_ET << " " << jmax.pT() << " " << s << " " << (jmax.pT())*s << std::endl;

      // merge
      if( shared_ET > (jmax.pT())*shared_ET_fraction 
	  && (imax.pT() > pT_min_leading_protojet || jmax.pT() > pT_min_second_protojet)
	  && (imax.info().nbMerge() < MergeMax || imax.pT() > pT_min_noMergeMax))
	{
	  // add neighbor's items to imax
	  const std::list<const Item*>& jlist(jmax.LItems());
	  typename std::list<const Item*>::const_iterator tk;
	  typename std::list<const Item*>::const_iterator iend= ilist.end();
	  bool same = true; // is jmax just the same as imax ? 
	  for(tk = jlist.begin(); tk != jlist.end(); ++tk) 
	    {
	      typename std::list<const Item*>::const_iterator where= 
		find(ilist.begin(),iend,*tk);   
	      if(where == iend) 
		{
		  imax.addItem(*tk);
		  same = false;
		}
	    }
	  if ( ! same ) 
	    {
	      // recalculate
	      //float old_pT = imax.pT();
	      
	      imax.updateJet();
	      imax.merged();
	      //std::cout << " jet merge :: " << old_pT << " " << jmax.pT() << " " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 
	    }
	}
      
      //split and assign removed shared cells from lowest pT protojet
      else if(shared_ET > (jmax.pT())*shared_ET_fraction)
      {
	// here we need to pull the lists, because there are items to remove                                                                           
	std::list<const Item*> ilist(imax.LItems());
	std::list<const Item*> jlist(jmax.LItems());

        typename std::list<const Item*>::iterator tk;
        for(tk = jlist.begin(); tk != jlist.end(); )
	  {
	    typename std::list<const Item*>::iterator where=
	      find(ilist.begin(),ilist.end(),*tk);
	    if(where != ilist.end()) {
	      tk = jlist.erase(tk);
	    }
	    else ++tk;
	  }
	
        jmax.erase();

        for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
              it != jlist.end(); ++it) jmax.addItem(*it);

        // recalculated jet quantities 
        jmax.updateJet();
        jmax.splitted();
        //std::cout << " jet split 1 :: " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl;                         
        _members.insert(std::make_pair(jmax,jmax.pT()));
      }

      // split and assign shared cells to nearest protojet
      else 
      {
	// here we need to pull the lists, because there are items to remove
	std::list<const Item*> ilist(imax.LItems());
	std::list<const Item*> jlist(jmax.LItems());
	
	typename std::list<const Item*>::iterator tk;
	for(tk = jlist.begin(); tk != jlist.end(); ) 
	{
	  typename std::list<const Item*>::iterator where= 
	    find(ilist.begin(),ilist.end(),*tk);
	  if(where != ilist.end()) {
	    float yk   = (*tk)->y();
	    float phik = (*tk)->phi();
	    float di= RD2(imax.y(),imax.phi(),yk,phik);
	    float dj= RD2(jmax.y(),jmax.phi(),yk,phik);
	    if(dj > di) 
	    {
	      tk = jlist.erase(tk);
	      //std::cout << " shared item " << (*tk)->pT() << " removed from neighbour jet " << std::endl;
	    }
	    else
	    {
	      ilist.erase(where);
	      ++tk;
	      //std::cout << " shared item " << (*tk)->pT() << " removed from leading jet " << std::endl;
	    }
	  }
	  else ++tk;
	}
	// recalculate jets imax and jmax
	
	// first erase all items
	imax.erase();
	// put items that are left
	for ( typename std::list<const Item*>::const_iterator it = ilist.begin();
	      it != ilist.end(); ++it) imax.addItem(*it);
	// recalculated jet quantities
	imax.updateJet();
	imax.splitted();
	//std::cout << " jet split 2 :: " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 


	// first erase all items
	jmax.erase();
	// put items that are left
	for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
	      it != jlist.end(); ++it) jmax.addItem(*it);
	// recalculated jet quantities
	jmax.updateJet();
	jmax.splitted();
	//std::cout << " jet split " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl; 

	_members.insert(std::make_pair(jmax,jmax.pT()));
      }
      _members.insert(std::make_pair(imax,imax.pT()));
    }
  } // while
}
コード例 #7
0
ファイル: dwarflines.cpp プロジェクト: Pascal-78/cv2pdb
bool interpretDWARFLines(const PEImage& img, mspdb::Mod* mod)
{
	for(unsigned long off = 0; off < img.debug_line_length; )
	{
		DWARF_LineNumberProgramHeader* hdr = (DWARF_LineNumberProgramHeader*) (img.debug_line + off);
		int length = hdr->unit_length;
		if(length < 0)
			break;
		length += sizeof(length);

		unsigned char* p = (unsigned char*) (hdr + 1);
		unsigned char* end = (unsigned char*) hdr + length;

		std::vector<unsigned int> opcode_lengths;
		opcode_lengths.resize(hdr->opcode_base);
		if (hdr->opcode_base > 0)
		{
			opcode_lengths[0] = 0;
			for(int o = 1; o < hdr->opcode_base && p < end; o++)
				opcode_lengths[o] = LEB128(p);
		}

		DWARF_LineState state;
		state.seg_offset = img.getImageBase() + img.getSection(img.codeSegment).VirtualAddress;

		// dirs
		while(p < end)
		{
			if(*p == 0)
				break;
			state.include_dirs.push_back((const char*) p);
			p += strlen((const char*) p) + 1;
		}
		p++;

		// files
		DWARF_FileName fname;
		while(p < end && *p)
		{
			fname.read(p);
			state.files.push_back(fname);
		}
		p++;

		state.init(hdr);
		while(p < end)
		{
			int opcode = *p++;
			if(opcode >= hdr->opcode_base)
			{
				// special opcode
				int adjusted_opcode = opcode - hdr->opcode_base;
				int operation_advance = adjusted_opcode / hdr->line_range;
				state.advance_addr(hdr, operation_advance);
				int line_advance = hdr->line_base + (adjusted_opcode % hdr->line_range);
				state.line += line_advance;

				state.addLineInfo();

				state.basic_block = false;
				state.prologue_end = false;
				state.epilogue_end = false;
				state.discriminator = 0;
			}
			else
			{
				switch(opcode)
				{
				case 0: // extended
				{
					int exlength = LEB128(p);
					unsigned char* q = p + exlength;
					int excode = *p++;
					switch(excode)
					{
					case DW_LNE_end_sequence:
						if((char*)p - img.debug_line >= 0xe4e0)
							p = p;
						state.end_sequence = true;
						state.last_addr = state.address;
						state.addLineInfo();
						if(!_flushDWARFLines(img, mod, state))
							return false;
						state.init(hdr);
						break;
					case DW_LNE_set_address:
                        if (!mod && state.section == -1)
                            state.section = img.getRelocationInLineSegment((char*)p - img.debug_line);
						if(unsigned long adr = RD4(p))
							state.address = adr;
						else if (!mod)
							state.address = adr;
                        else
							state.address = state.last_addr; // strange adr 0 for templates?
						state.op_index = 0;
						break;
					case DW_LNE_define_file:
						fname.read(p);
						state.file_ptr = &fname;
						state.file = 0;
						break;
					case DW_LNE_set_discriminator:
						state.discriminator = LEB128(p);
						break;
					}
					p = q;
					break;
				}
				case DW_LNS_copy:
					state.addLineInfo();
					state.basic_block = false;
					state.prologue_end = false;
					state.epilogue_end = false;
					state.discriminator = 0;
					break;
				case DW_LNS_advance_pc:
					state.advance_addr(hdr, LEB128(p));
					break;
				case DW_LNS_advance_line:
					state.line += SLEB128(p);
					break;
				case DW_LNS_set_file:
					if(!_flushDWARFLines(img, mod, state))
						return false;
					state.file = LEB128(p);
					break;
				case DW_LNS_set_column:
					state.column = LEB128(p);
					break;
				case DW_LNS_negate_stmt:
					state.is_stmt = !state.is_stmt;
					break;
				case DW_LNS_set_basic_block:
					state.basic_block = true;
					break;
				case DW_LNS_const_add_pc:
					state.advance_addr(hdr, (255 - hdr->opcode_base) / hdr->line_range);
					break;
				case DW_LNS_fixed_advance_pc:
					state.address += RD2(p);
					state.op_index = 0;
					break;
				case DW_LNS_set_prologue_end:
					state.prologue_end = true;
					break;
				case DW_LNS_set_epilogue_begin:
					state.epilogue_end = true;
					break;
				case DW_LNS_set_isa:
					state.isa = LEB128(p);
					break;
				default:
					// unknown standard opcode
					for(unsigned int arg = 0; arg < opcode_lengths[opcode]; arg++)
						LEB128(p);
					break;
				}
			}
		}
		if(!_flushDWARFLines(img, mod, state))
			return false;

		off += length;
	}

	return true;
}
コード例 #8
0
ファイル: readDwarf.cpp プロジェクト: Pascal-78/cv2pdb
Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase, int at)
{
	static Location invalid = { Location::Invalid };

	if (attr.type == Const)
		return mkAbs(attr.cons);

	if (attr.type != ExprLoc && attr.type != Block) // same memory layout
		return invalid;

	byte* p = attr.expr.ptr;
	Location stack[256];
	int stackDepth = 0;
    if (at == DW_AT_data_member_location)
        stack[stackDepth++] = Location { Location::Abs, 0, 0 };

	for (;;)
	{
		if (p >= attr.expr.ptr + attr.expr.len)
			break;

		int op = *p++;
		if (op == 0)
			break;

		switch (op)
		{
			case DW_OP_reg0:  case DW_OP_reg1:  case DW_OP_reg2:  case DW_OP_reg3:
			case DW_OP_reg4:  case DW_OP_reg5:  case DW_OP_reg6:  case DW_OP_reg7:
			case DW_OP_reg8:  case DW_OP_reg9:  case DW_OP_reg10: case DW_OP_reg11:
			case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15:
			case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19:
			case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
			case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27:
			case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31:
				stack[stackDepth++] = mkInReg(op - DW_OP_reg0);
				break;
			case DW_OP_regx:
				stack[stackDepth++] = mkInReg(LEB128(p));
				break;

			case DW_OP_const1u: stack[stackDepth++] = mkAbs(*p); break;
			case DW_OP_const2u: stack[stackDepth++] = mkAbs(RD2(p)); break;
			case DW_OP_const4u: stack[stackDepth++] = mkAbs(RD4(p)); break;
			case DW_OP_const1s: stack[stackDepth++] = mkAbs((char)*p); break;
			case DW_OP_const2s: stack[stackDepth++] = mkAbs((short)RD2(p)); break;
			case DW_OP_const4s: stack[stackDepth++] = mkAbs((int)RD4(p)); break;
			case DW_OP_constu:  stack[stackDepth++] = mkAbs(LEB128(p)); break;
			case DW_OP_consts:  stack[stackDepth++] = mkAbs(SLEB128(p)); break;

			case DW_OP_plus_uconst: 
				if (stack[stackDepth - 1].is_inreg())
					return invalid;
				stack[stackDepth - 1].off += LEB128(p); 
				break;

			case DW_OP_lit0:  case DW_OP_lit1:  case DW_OP_lit2:  case DW_OP_lit3:
			case DW_OP_lit4:  case DW_OP_lit5:  case DW_OP_lit6:  case DW_OP_lit7:
			case DW_OP_lit8:  case DW_OP_lit9:  case DW_OP_lit10: case DW_OP_lit11:
			case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15:
			case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19:
			case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
				stack[stackDepth++] = mkAbs(op - DW_OP_lit0);
				break;

			case DW_OP_breg0:  case DW_OP_breg1:  case DW_OP_breg2:  case DW_OP_breg3:
			case DW_OP_breg4:  case DW_OP_breg5:  case DW_OP_breg6:  case DW_OP_breg7:
			case DW_OP_breg8:  case DW_OP_breg9:  case DW_OP_breg10: case DW_OP_breg11:
			case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15:
			case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19:
			case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
			case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27:
			case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:
				stack[stackDepth++] = mkRegRel(op - DW_OP_breg0, SLEB128(p));
				break;
			case DW_OP_bregx:
			{
				unsigned reg = LEB128(p);
				stack[stackDepth++] = mkRegRel(reg, SLEB128(p));
			}   break;


			case DW_OP_abs: case DW_OP_neg: case DW_OP_not:
			{
				Location& op1 = stack[stackDepth - 1];
				if (!op1.is_abs())
					return invalid;
				switch (op)
				{
					case DW_OP_abs:   op1 = mkAbs(abs(op1.off)); break;
					case DW_OP_neg:   op1 = mkAbs(-op1.off); break;
					case DW_OP_not:   op1 = mkAbs(~op1.off); break;
				}
			}   break;

			case DW_OP_plus:  // op2 + op1
			{
				Location& op1 = stack[stackDepth - 1];
				Location& op2 = stack[stackDepth - 2];
				// Can add only two offsets or a regrel and an offset.
				if (op2.is_regrel() && op1.is_abs())
					op2 = mkRegRel(op2.reg, op2.off + op1.off);
				else if (op2.is_abs() && op1.is_regrel())
					op2 = mkRegRel(op1.reg, op2.off + op1.off);
				else if (op2.is_abs() && op1.is_abs())
					op2 = mkAbs(op2.off + op1.off);
				else
					return invalid;
				--stackDepth;
			}   break;

			case DW_OP_minus: // op2 - op1
			{
				Location& op1 = stack[stackDepth - 1];
				Location& op2 = stack[stackDepth - 2];
				if (op2.is_regrel() && op1.is_regrel() && op2.reg == op1.reg)
					op2 = mkAbs(0); // X - X == 0
				else if (op2.is_regrel() && op1.is_abs())
					op2 = mkRegRel(op2.reg, op2.off - op1.off);
				else if (op2.is_abs() && op1.is_abs())
					op2 = mkAbs(op2.off - op1.off);
				else
					return invalid;
				--stackDepth;
			}   break;

			case DW_OP_mul:
			{
				Location& op1 = stack[stackDepth - 1];
				Location& op2 = stack[stackDepth - 2];
				if ((op1.is_abs() && op1.off == 0) || (op2.is_abs() && op2.off == 0))
					op2 = mkAbs(0); // X * 0 == 0
				else if (op1.is_abs() && op2.is_abs())
					op2 = mkAbs(op1.off * op2.off);
				else
					return invalid;
				--stackDepth;
			}   break;

			case DW_OP_and:
			{
				Location& op1 = stack[stackDepth - 1];
				Location& op2 = stack[stackDepth - 2];
				if ((op1.is_abs() && op1.off == 0) || (op2.is_abs() && op2.off == 0))
					op2 = mkAbs(0); // X & 0 == 0
				else if (op1.is_abs() && op2.is_abs())
					op2 = mkAbs(op1.off & op2.off);
				else
					return invalid;
				--stackDepth;
			}   break;

			case DW_OP_div: case DW_OP_mod: case DW_OP_shl:
			case DW_OP_shr: case DW_OP_shra: case DW_OP_or:
			case DW_OP_xor:
			case DW_OP_eq:  case DW_OP_ge:  case DW_OP_gt:
			case DW_OP_le:  case DW_OP_lt:  case DW_OP_ne:
			{
				Location& op1 = stack[stackDepth - 1];
				Location& op2 = stack[stackDepth - 2];
				if (!op1.is_abs() || !op2.is_abs()) // can't combine unless both are constants
					return invalid;
				switch (op)
				{
					case DW_OP_div:   op2.off = op2.off / op1.off; break;
					case DW_OP_mod:   op2.off = op2.off % op1.off; break;
					case DW_OP_shl:   op2.off = op2.off << op1.off; break;
					case DW_OP_shr:   op2.off = op2.off >> op1.off; break;
					case DW_OP_shra:  op2.off = op2.off >> op1.off; break;
					case DW_OP_or:    op2.off = op2.off | op1.off; break;
					case DW_OP_xor:   op2.off = op2.off ^ op1.off; break;
					case DW_OP_eq:    op2.off = op2.off == op1.off; break;
					case DW_OP_ge:    op2.off = op2.off >= op1.off; break;
					case DW_OP_gt:    op2.off = op2.off > op1.off; break;
					case DW_OP_le:    op2.off = op2.off <= op1.off; break;
					case DW_OP_lt:    op2.off = op2.off < op1.off; break;
					case DW_OP_ne:    op2.off = op2.off != op1.off; break;
				}
				--stackDepth;
			}   break;

			case DW_OP_fbreg:
			{
				if (!frameBase)
					return invalid;

				Location loc;
				if (frameBase->is_inreg()) // ok in frame base specification, per DWARF4 spec #3.3.5
					loc = mkRegRel(frameBase->reg, SLEB128(p));
				else if (frameBase->is_regrel())
					loc = mkRegRel(frameBase->reg, frameBase->off + SLEB128(p));
				else
					return invalid;
				stack[stackDepth++] = loc;
			}   break;

			case DW_OP_dup:   stack[stackDepth] = stack[stackDepth - 1]; stackDepth++; break;
			case DW_OP_drop:  stackDepth--; break;
			case DW_OP_over:  stack[stackDepth] = stack[stackDepth - 2]; stackDepth++; break;
			case DW_OP_pick:  stack[stackDepth++] = stack[*p]; break;
			case DW_OP_swap:  { Location tmp = stack[stackDepth - 1]; stack[stackDepth - 1] = stack[stackDepth - 2]; stack[stackDepth - 2] = tmp; } break;
			case DW_OP_rot:   { Location tmp = stack[stackDepth - 1]; stack[stackDepth - 1] = stack[stackDepth - 2]; stack[stackDepth - 2] = stack[stackDepth - 3]; stack[stackDepth - 3] = tmp; } break;

			case DW_OP_addr:
				stack[stackDepth++] = mkAbs(RD4(p)); // TODO: 64-bit
				break;

			case DW_OP_skip:
			{
				unsigned off = RD2(p);
				p = p + off;
			}   break;

			case DW_OP_bra:
			{
				Location& op1 = stack[stackDepth - 1];
				if (!op1.is_abs())
					return invalid;
				if (op1.off != 0)
				{
					unsigned off = RD2(p);
					p = p + off;
				}
				--stackDepth;
			}   break;

			case DW_OP_nop:
				break;

			case DW_OP_call_frame_cfa: // assume ebp+8/rbp+16
				stack[stackDepth++] = Location{ Location::RegRel, DW_REG_CFA, 0 };
				break;

			case DW_OP_deref:
			case DW_OP_deref_size:
			case DW_OP_push_object_address:
			case DW_OP_call2:
			case DW_OP_call4:
			case DW_OP_form_tls_address:
			case DW_OP_call_ref:
			case DW_OP_bit_piece:
			case DW_OP_implicit_value:
			case DW_OP_stack_value:
			default:
				return invalid;
		}
	}

	assert(stackDepth > 0);
	return stack[0];
}
コード例 #9
0
ファイル: readDwarf.cpp プロジェクト: Pascal-78/cv2pdb
bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
{
	id.clear();

	if (hasChild)
		++level;

	for (;;)
	{
		if (level == -1)
			return false; // we were already at the end of the subtree

		if (ptr >= ((byte*)cu + sizeof(cu->unit_length) + cu->unit_length))
			return false; // root of the tree does not have a null terminator, but we know the length

		id.entryPtr = ptr;
		id.entryOff = ptr - (byte*)cu;
		id.code = LEB128(ptr);
		if (id.code == 0)
		{
			--level; // pop up one level
			if (stopAtNull)
			{
				hasChild = false;
				return false;
			}
			continue; // read the next DIE
		}

		break;
	}

	byte* abbrev = getDWARFAbbrev(cu->debug_abbrev_offset, id.code);
	assert(abbrev);
	if (!abbrev)
		return false;

	id.abbrev = abbrev;
	id.tag = LEB128(abbrev);
	id.hasChild = *abbrev++;

	int attr, form;
	for (;;)
	{
		attr = LEB128(abbrev);
		form = LEB128(abbrev);

		if (attr == 0 && form == 0)
			break;

		while (form == DW_FORM_indirect)
			form = LEB128(ptr);

		DWARF_Attribute a;
		switch (form)
		{
			case DW_FORM_addr:           a.type = Addr; a.addr = (unsigned long)RDsize(ptr, cu->address_size); break;
			case DW_FORM_block:          a.type = Block; a.block.len = LEB128(ptr); a.block.ptr = ptr; ptr += a.block.len; break;
			case DW_FORM_block1:         a.type = Block; a.block.len = *ptr++;      a.block.ptr = ptr; ptr += a.block.len; break;
			case DW_FORM_block2:         a.type = Block; a.block.len = RD2(ptr);   a.block.ptr = ptr; ptr += a.block.len; break;
			case DW_FORM_block4:         a.type = Block; a.block.len = RD4(ptr);   a.block.ptr = ptr; ptr += a.block.len; break;
			case DW_FORM_data1:          a.type = Const; a.cons = *ptr++; break;
			case DW_FORM_data2:          a.type = Const; a.cons = RD2(ptr); break;
			case DW_FORM_data4:          a.type = Const; a.cons = RD4(ptr); break;
			case DW_FORM_data8:          a.type = Const; a.cons = RD8(ptr); break;
			case DW_FORM_sdata:          a.type = Const; a.cons = SLEB128(ptr); break;
			case DW_FORM_udata:          a.type = Const; a.cons = LEB128(ptr); break;
			case DW_FORM_string:         a.type = String; a.string = (const char*)ptr; ptr += strlen(a.string) + 1; break;
            case DW_FORM_strp:           a.type = String; a.string = (const char*)(img->debug_str + RDsize(ptr, cu->isDWARF64() ? 8 : 4)); break;
			case DW_FORM_flag:           a.type = Flag; a.flag = (*ptr++ != 0); break;
			case DW_FORM_flag_present:   a.type = Flag; a.flag = true; break;
			case DW_FORM_ref1:           a.type = Ref; a.ref = (byte*)cu + *ptr++; break;
			case DW_FORM_ref2:           a.type = Ref; a.ref = (byte*)cu + RD2(ptr); break;
			case DW_FORM_ref4:           a.type = Ref; a.ref = (byte*)cu + RD4(ptr); break;
			case DW_FORM_ref8:           a.type = Ref; a.ref = (byte*)cu + RD8(ptr); break;
			case DW_FORM_ref_udata:      a.type = Ref; a.ref = (byte*)cu + LEB128(ptr); break;
			case DW_FORM_ref_addr:       a.type = Ref; a.ref = (byte*)img->debug_info + (cu->isDWARF64() ? RD8(ptr) : RD4(ptr)); break;
			case DW_FORM_ref_sig8:       a.type = Invalid; ptr += 8;  break;
			case DW_FORM_exprloc:        a.type = ExprLoc; a.expr.len = LEB128(ptr); a.expr.ptr = ptr; ptr += a.expr.len; break;
			case DW_FORM_sec_offset:     a.type = SecOffset;  a.sec_offset = cu->isDWARF64() ? RD8(ptr) : RD4(ptr); break;
			case DW_FORM_indirect:
			default: assert(false && "Unsupported DWARF attribute form"); return false;
		}

		switch (attr)
		{
			case DW_AT_byte_size: 
				assert(a.type == Const || a.type == Ref || a.type == ExprLoc);
				if (a.type == Const) // TODO: other types not supported yet
					id.byte_size = a.cons; 
				break;
			case DW_AT_sibling:   assert(a.type == Ref); id.sibling = a.ref; break;
			case DW_AT_encoding:  assert(a.type == Const); id.encoding = a.cons; break;
			case DW_AT_name:      assert(a.type == String); id.name = a.string; break;
			case DW_AT_MIPS_linkage_name: assert(a.type == String); id.linkage_name = a.string; break;
			case DW_AT_comp_dir:  assert(a.type == String); id.dir = a.string; break;
			case DW_AT_low_pc:    assert(a.type == Addr); id.pclo = a.addr; break;
			case DW_AT_high_pc:
				if (a.type == Addr)
					id.pchi = a.addr;
				else if (a.type == Const)
					id.pchi = id.pclo + a.cons;
				else
					assert(false);
			    break;
			case DW_AT_ranges:
				if (a.type == SecOffset)
					id.ranges = a.sec_offset;
				else if (a.type == Const)
					id.ranges = a.cons;
				else
					assert(false);
			    break;
			case DW_AT_type:      assert(a.type == Ref); id.type = a.ref; break;
			case DW_AT_inline:    assert(a.type == Const); id.inlined = a.cons; break;
			case DW_AT_external:  assert(a.type == Flag); id.external = a.flag; break;
			case DW_AT_upper_bound: 
				assert(a.type == Const || a.type == Ref || a.type == ExprLoc);
				if (a.type == Const) // TODO: other types not supported yet
					id.upper_bound = a.cons;
				break;
			case DW_AT_lower_bound: 
				assert(a.type == Const || a.type == Ref || a.type == ExprLoc);
				if (a.type == Const) // TODO: other types not supported yet
					id.lower_bound = a.cons;
				break;
			case DW_AT_containing_type: assert(a.type == Ref); id.containing_type = a.ref; break;
			case DW_AT_specification: assert(a.type == Ref); id.specification = a.ref; break;
			case DW_AT_data_member_location: id.member_location = a; break;
			case DW_AT_location: id.location = a; break;
			case DW_AT_frame_base: id.frame_base = a; break;
		}
	}

	hasChild = id.hasChild != 0;
	sibling = id.sibling;

	return true;
}