LONG cop_request(LONG cob_id, SHORT *length, BYTE *data) { WORD timeout[9] = {2,2,2,2,2,2,5,10,20}; BYTE dlc = (BYTE)*length; // 1. Configure receive message object with remote request if((cop_error = can_config(CANBUF_RX, cob_id, (WORD)CAN_REQUEST(dlc))) != CANERR_NOERROR) { can_delete(CANBUF_RX); return cop_error; } // 2. Start timer (increased time-out for RTR-frames) can_start_timer((WORD)(timeout[cop_baudrate] * CANRTR_FACTOR)); // 3. Wait until message is received do { // Return if a message is received, or an error occurred if((cop_error = can_receive(CANBUF_RX, length, data)) != COPERR_RX_EMPTY) { can_delete(CANBUF_RX); return cop_error; } } while(!can_is_timeout()); // 4. A time-out occurred! can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; }
void remove_unused_fields(Scope& scope, const std::vector<std::string>& remove_members) { std::vector<DexField*> moveable_fields; std::vector<DexClass*> smallscope; uint32_t aflags = ACC_STATIC | ACC_FINAL; for (auto clazz : scope) { bool found = can_delete(clazz); if (!found) { auto name = clazz->get_name()->c_str(); for (const auto& name_prefix : remove_members) { if (strstr(name, name_prefix.c_str()) != nullptr) { found = true; break; } } if (!found) { TRACE(FINALINLINE, 2, "Cannot delete: %s\n", SHOW(clazz)); continue; } } auto sfields = clazz->get_sfields(); for (auto sfield : sfields) { if ((sfield->get_access() & aflags) != aflags) continue; auto value = sfield->get_static_value(); if (value == nullptr && !is_primitive(sfield->get_type())) continue; if (!found && !can_delete(sfield)) continue; moveable_fields.push_back(sfield); smallscope.push_back(clazz); } } sort_unique(smallscope); std::unordered_set<DexField*> field_target = get_field_target(scope, moveable_fields); std::unordered_set<DexField*> dead_fields; for (auto field : moveable_fields) { if (field_target.count(field) == 0) { dead_fields.insert(field); } } TRACE(FINALINLINE, 1, "Removable fields %lu/%lu\n", dead_fields.size(), moveable_fields.size()); TRACE(FINALINLINE, 1, "Unhandled inline %ld\n", unhandled_inline); for (auto clazz : smallscope) { auto& sfields = clazz->get_sfields(); auto iter = sfields.begin(); while (iter != sfields.end()) { auto todel = iter++; if (dead_fields.count(*todel) > 0) { sfields.erase(todel); } } } }
void reportReachableClasses(const Scope& scope, std::string reportFileName) { TRACE(PGR, 4, "Total numner of classes: %d\n", scope.size()); // Report classes that the reflection filter says can't be deleted. std::ofstream reportFileCanDelete(reportFileName + ".cant_delete"); for (auto const& cls : scope) { if (!can_delete(cls)) { reportFileCanDelete << cls->get_name()->c_str() << "\n"; } } reportFileCanDelete.close(); // Report classes that the reflection filter says can't be renamed. std::ofstream reportFileCanRename(reportFileName + ".cant_rename"); for (auto const& cls : scope) { if (!can_rename(cls)) { reportFileCanRename << cls->get_name()->c_str() << "\n"; } } reportFileCanRename.close(); // Report classes marked for keep from ProGuard flat file list. std::ofstream reportFileKeep(reportFileName + ".must_keep"); for (auto const& cls : scope) { if (is_seed(cls)) { reportFileKeep << cls->get_name()->c_str() << "\n"; } } reportFileKeep.close(); }
/* unlink can delete the (disk or memory)inode directly. */ int minix_inode_unlink(struct inode *dir, char *base, int len, int (*can_delete)(struct inode *)) { struct block *block; /* dir entry block */ struct minix_dentry *de; struct inode *inode; int r = -1; de = minix_lookup_dentry(dir, base, len, &block); if (!de) return -1; inode = minix_get_inode(dir->i_sb, de->d_ino); if (!inode) goto out_put_block; /* permission check */ if (inode->i_refcnt > 1) goto out_put_inode; if (can_delete && !can_delete(inode)) goto out_put_inode; /* delete it from the data block of dir */ memset(de, 0x0, MINIX_DENTRY_SIZE); minix_inode_dirty_block(dir, block); /* delete inode */ minix_dec_link(inode); minix_put_inode(inode); r = 0; out_put_inode: put_inode(inode); out_put_block: put_block(block); return r; }
LONG cop_transmit(LONG cob_id, SHORT length, BYTE *data) { // 1. Configure transmit message object if((cop_error = can_config(CANBUF_TX, cob_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) { can_delete(CANBUF_TX); return cop_error; } // 2. Transmit the message if((cop_error = can_transmit(CANBUF_TX, length, data)) != CANERR_NOERROR) { can_delete(CANBUF_TX); return cop_error; } // Return if the message is transmitted can_delete(CANBUF_TX); return cop_error; }
bool should_rename(DexClass *clazz, std::vector<std::string>& pre_patterns, std::vector<std::string>& post_patterns, std::unordered_set<const DexType*>& untouchables, bool rename_annotations, PassManager& mgr) { if (!rename_annotations && is_annotation(clazz)) { mgr.incr_metric(METRIC_CANT_RENAME_ANNOTATION, 1); return false; } if (untouchables.count(clazz->get_type())) { mgr.incr_metric(METRIC_CANT_RENAME_UNTOUCHABLE, 1); return false; } auto chstring = clazz->get_type()->get_name()->c_str(); /* We're assuming anonymous classes are safe always safe to rename. */ auto last_cash = strrchr(chstring, '$'); if (last_cash != nullptr) { auto val = *++last_cash; if (val >= '0' && val <= '9') { match_inner++; return true; } } /* Check for more aggressive, but finer grained filters first */ for (auto p : pre_patterns) { auto substr = strstr(chstring, p.c_str()); if (substr != nullptr) { if (p.length() > 1) { match_long++; } else { match_short++; } return true; } } if (!can_rename(clazz) && !can_delete(clazz)) { mgr.incr_metric(METRIC_CANT_RENAME_AND_CANT_DELETE, 1); return false; } /* Check for wider, less precise filters */ for (auto p : post_patterns) { auto substr = strstr(chstring, p.c_str()); if (substr != nullptr) { if (p.length() > 1) { match_long++; } else { match_short++; } return true; } } mgr.incr_metric(METRIC_NOT_WHITELISTED, 1); return false; }
void remove_unused_fields(Scope& scope, const std::unordered_set<DexType*>& keep_annos, const std::unordered_set<DexField*>& keep_members) { std::vector<DexField*> moveable_fields; std::vector<DexClass*> smallscope; uint32_t aflags = ACC_STATIC | ACC_FINAL; for (auto clazz : scope) { if (!can_delete(clazz)) { continue; } auto sfields = clazz->get_sfields(); for (auto sfield : sfields) { if ((sfield->get_access() & aflags) != aflags) continue; auto value = sfield->get_static_value(); if (value == nullptr && !is_primitive(sfield->get_type())) continue; if (is_kept_by_annotation(sfield, keep_annos)) continue; if (is_kept_member(sfield, keep_members)) continue; moveable_fields.push_back(sfield); smallscope.push_back(clazz); } } sort_unique(smallscope); std::unordered_set<DexField*> field_target = get_field_target(scope, moveable_fields); std::unordered_set<DexField*> dead_fields; for (auto field : moveable_fields) { if (field_target.count(field) == 0) { dead_fields.insert(field); } } TRACE(FINALINLINE, 1, "Removable fields %lu/%lu\n", dead_fields.size(), moveable_fields.size()); TRACE(FINALINLINE, 1, "Unhandled inline %ld\n", unhandled_inline); for (auto clazz : smallscope) { auto& sfields = clazz->get_sfields(); auto iter = sfields.begin(); while (iter != sfields.end()) { auto todel = iter++; if (dead_fields.count(*todel) > 0) { sfields.erase(todel); } } } }
bool should_rename(DexClass *clazz, std::vector<std::string>& pre_patterns, std::vector<std::string>& post_patterns, std::unordered_set<const DexType*>& untouchables, bool rename_annotations) { if (!rename_annotations && is_annotation(clazz)) return false; if (untouchables.count(clazz->get_type())) return false; auto chstring = clazz->get_type()->get_name()->c_str(); /* We're assuming anonymous classes are safe always safe to rename. */ auto substr = strrchr(chstring, '$'); if (substr != nullptr) { auto val = *++substr; if (val >= '0' && val <= '9') { match_inner++; return true; } } /* Check for more aggressive, but finer grained filters first */ for (auto p : pre_patterns) { auto substr = strstr(chstring, p.c_str()); if (substr != nullptr) { if (p.length() > 1) { match_long++; } else { match_short++; } return true; } } if (!can_rename(clazz) && !can_delete(clazz)) { return false; } /* Check for wider, less precise filters */ for (auto p : post_patterns) { auto substr = strstr(chstring, p.c_str()); if (substr != nullptr) { if (p.length() > 1) { match_long++; } else { match_short++; } return true; } } return false; }
HRESULT STDMETHODCALLTYPE CProjectItemInfo::get_InfoProperty(TC_PROJECT_NODE_INFO_PROP PropID, VARIANT * Value) { _ASSERT( Value != NULL ); CComVariant default_node_name (cDefaultName); CComVariant bitmap ((LONG)m_bitmap); CComVariant name (cProjectItemName); CComVariant description (cProjectItemDescription); CComVariant description_ex (cProjectItemDescription_ex); CComVariant help_context (0); CComVariant help_context_file_name(_T("")); CComVariant help_topic (_T("")); CComVariant help_topic_file_name (_T("")); CComVariant is_alone (true); CComVariant is_required (false); CComVariant can_edit_name (false); CComVariant can_delete (true); CComVariant recorder_create_only (false); switch (PropID) { case pniDefaultNodeName: return VariantCopy(Value, &default_node_name); case pniBitmapReference: return VariantCopy(Value, &bitmap); case pniName: return VariantCopy(Value, &name); case pniDescription: return VariantCopy(Value, &description); case pniDescriptionEx: return VariantCopy(Value, &description_ex); case pniHelpContext: return VariantCopy(Value, &help_context); case pniHelpContextFileName: return VariantCopy(Value, &help_context_file_name); case pniHelpTopic: return VariantCopy(Value, &help_topic); case pniHelpTopicFileName: return VariantCopy(Value, &help_topic_file_name); case pniIsAlone: return VariantCopy(Value, &is_alone); case pniIsRequired: return VariantCopy(Value, &is_required); case pniCanEditName: return VariantCopy(Value, &can_edit_name); case pniCanDelete: return VariantCopy(Value, &can_delete); case pniRecorderCreateOnly: return VariantCopy(Value, &recorder_create_only); default: _ASSERT( false ); return ERROR_BAD_ARGUMENTS; } }
static LONG sdo_receive(BYTE node_id, WORD index, BYTE subindex, SHORT *length, BYTE *data, SHORT max) { short n; // data length code short rc; // return value short t = 0; // toggle bit // --- Initiate SDO Upload --- cop_buffer[0] = 0x40; // client command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = 0x00; // reserved: set to 00h cop_buffer[5] = 0x00; // -"- cop_buffer[6] = 0x00; // -"- cop_buffer[7] = 0x00; // -"- n = 8; // 8 bytes to transmit! // 1. Configure transmit message object for client SDO if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) { can_delete(CANBUF_TX); return cop_error; } // 2. Configure receive message object for server SDO if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 2. Transmit the client SDO message if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 3. Start timer for SDO time-out can_start_timer(cop_timeout); // 4. Wait until server message is received do { switch((rc = can_receive(CANBUF_RX, &n, cop_buffer))) { case CANERR_NOERROR: // confirmation: if(n != 8) { // 8 bytes received? cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_LENGTH; } if((cop_buffer[1] != LOBYTE(index)) || // multiplexor? index (LSB) (cop_buffer[2] != HIBYTE(index)) || // index (MSB) (cop_buffer[3] != (BYTE)(subindex))) { // subindex rc = COPERR_FORMAT; break; } if((cop_buffer[0] & 0xE0) == 0x80) {// SDO abort received? LOLOBYTE(cop_error) = cop_buffer[4]; // abort code (LSB) LOHIBYTE(cop_error) = cop_buffer[5]; // -"- HILOBYTE(cop_error) = cop_buffer[6]; // -"- HIHIBYTE(cop_error) = cop_buffer[7]; // abort code (MSB) *length = 0; // no data received! // Return value is abort code! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } if((cop_buffer[0] & 0xE0) != 0x40) { // unknown command specifier? cop_error = SDOERR_UNKNOWN_SPECIFIER; // abort: unknown command specifier cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } if((cop_buffer[0] & 0x02) == 0x02) { // expedited transfer? if((cop_buffer[0] & 0x01) == 0x01) n = 4 - (short)((cop_buffer[0] & 0x0C) >> 2); else n = 4; memcpy(data, &cop_buffer[4], n < max? n : max); *length = n < max? n : max; // data received!!! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_NOERROR; } break; case CANERR_RX_EMPTY: // receiver empty: if(can_is_timeout()) { // time-out occurred? cop_error = SDOERR_PROTOCOL_TIMEOUT; // abort: time-out cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; } break; default: // other errors: cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = rc; } } while(rc != CANERR_NOERROR); // segmented transfer: // --- Upload SDO Segment --- for(*length = 0;;) { cop_buffer[0] = 0x60 | t; // client command specifier cop_buffer[1] = 0x00; // reserved: set to 00h cop_buffer[2] = 0x00; // -"- cop_buffer[3] = 0x00; // -"- cop_buffer[4] = 0x00; // -"- cop_buffer[5] = 0x00; // -"- cop_buffer[6] = 0x00; // -"- cop_buffer[7] = 0x00; // -"- n = 8; // 8 bytes to transmit! // 5. Transmit the client SDO message if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 6. Start timer for SDO time-out can_start_timer(cop_timeout); // 7. Wait until server message is received do { switch((rc = can_receive(CANBUF_RX, &n, cop_buffer))) { case CANERR_NOERROR: // confirmation: if(n != 8) { // 8 bytes received? cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_LENGTH; } if((cop_buffer[0] & 0xE0) == 0x80) {// SDO abort received? LOLOBYTE(cop_error) = cop_buffer[4]; // abort code (LSB) LOHIBYTE(cop_error) = cop_buffer[5]; // -"- HILOBYTE(cop_error) = cop_buffer[6]; // -"- HIHIBYTE(cop_error) = cop_buffer[7]; // abort code (MSB) *length = 0; // no data received! // Return value is abort code! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } if((cop_buffer[0] & 0xE0) != 0x00) { // unknown command specifier? cop_error = SDOERR_UNKNOWN_SPECIFIER; // abort: unknown command specifier cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } if((cop_buffer[0] & 0x10) != t) { // toggle bit not altered? cop_error = SDOERR_WRONG_TOGGLEBIT; // abort: toggle bit not altered cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } if((cop_buffer[0] & 0x0E) != 0x00) // number of segment data bytes n = 7 - (int)((cop_buffer[0] & 0x0E) >> 1); else n = 7; if(max - *length > 0) // copy segment data if space memcpy(&data[*length], &cop_buffer[1], *length + n < max? n : max - *length); *length += n; if((cop_buffer[0] & 0x01) == 0x01) { // no more segments? if(*length > max) *length = max; // truncate to buffer size! if(*length < max) data[*length] = '\0'; // for zero-closed strings! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_NOERROR; } break; case CANERR_RX_EMPTY: // receiver empty: if(can_is_timeout()) { // time-out occurred? cop_error = SDOERR_PROTOCOL_TIMEOUT; // abort: time-out cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; } break; default: // other errors: cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) *length = 0; // no data received! // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = rc; } } while(rc != CANERR_NOERROR); t = t? 0x00 : 0x10; // alternate toggle bit! } }
static LONG sdo_segmented(BYTE node_id, WORD index, BYTE subindex, SHORT length, BYTE *data) { short n, i; // data length code short rc; // return value short t = 0; // toggle bit // --- Initiate SDO Download --- cop_buffer[0] = (BYTE)0x21; // client command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOBYTE(length); // number of data bytes (LSB) cop_buffer[5] = HIBYTE(length); // -"- cop_buffer[6] = (BYTE)0x00; // -"- cop_buffer[7] = (BYTE)0x00; // number of data bytes (MSB) n = 8; // 8 bytes to transmit! // 1. Configure transmit message object for client SDO if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) { can_delete(CANBUF_TX); return cop_error; } // 2. Configure receive message object for server SDO if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 2. Transmit the client SDO message if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 3. Start timer for SDO time-out can_start_timer(cop_timeout); // 4. Wait until server message is received do { switch((rc = can_receive(CANBUF_RX, &n, cop_buffer))) { case CANERR_NOERROR: // confirmation: if(n != 8) { // 8 bytes received? cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_LENGTH; } if((cop_buffer[1] != LOBYTE(index)) || // multiplexor? index (LSB) (cop_buffer[2] != HIBYTE(index)) || // index (MSB) (cop_buffer[3] != (BYTE)(subindex))) { // subindex rc = COPERR_FORMAT; break; } if((cop_buffer[0] & 0xFF) == 0x80) { // SDO abort received? LOLOBYTE(cop_error) = cop_buffer[4]; // abort code (LSB) LOHIBYTE(cop_error) = cop_buffer[5]; // -"- HILOBYTE(cop_error) = cop_buffer[6]; // -"- HIHIBYTE(cop_error) = cop_buffer[7]; // abort code (MSB) // Return value is abort code! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } if((cop_buffer[0] & 0xFF) != 0x60) { // unknown command specifier? cop_error = SDOERR_UNKNOWN_SPECIFIER; // abort: unknown command specifier cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } case CANERR_RX_EMPTY: // receiver empty: if(can_is_timeout()) { // time-out occurred? cop_error = SDOERR_PROTOCOL_TIMEOUT; // abort: time-out cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; } break; default: // other errors: cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = rc; } } while(rc != CANERR_NOERROR); // --- Download SDO Segment --- for(i = 0;;) { if(length <= 7) // bytes that does not contain data n = 7 - length; else // no segment size indicated n = 0; cop_buffer[0] = (BYTE)(n << 1); // client command specifier memset(&cop_buffer[1], 0x00, 7);// clear data buffer memcpy(&cop_buffer[1], &data[i], 7 - n);// copy segment data length -= 7 - n; // remaining number of bytes i += 7 - n; // index to remainung bytes cop_buffer[0]|= length? 0x00 : 0x01;// last segment to transmit cop_buffer[0]|= t; // toggle bit n = 8; // 8 bytes to transmit! // 5. Transmit the client SDO message if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 6. Start timer for SDO time-out can_start_timer(cop_timeout); // 7. Wait until server message is received do { switch((rc = can_receive(CANBUF_RX, &n, cop_buffer))) { case CANERR_NOERROR: // confirmation: if(n != 8) { // 8 bytes received? cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_LENGTH; } if((cop_buffer[0] & 0xE0) == 0x80) { // SDO abort received? LOLOBYTE(cop_error) = cop_buffer[4]; // abort code (LSB) LOHIBYTE(cop_error) = cop_buffer[5]; // -"- HILOBYTE(cop_error) = cop_buffer[6]; // -"- HIHIBYTE(cop_error) = cop_buffer[7]; // abort code (MSB) // Return value is abort code! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } if((cop_buffer[0] & 0xE0) != 0x20) { // unknown command specifier? cop_error = SDOERR_UNKNOWN_SPECIFIER; // abort: unknown command specifier cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } if((cop_buffer[0] & 0x10) != t) { // toggle bit not altered? cop_error = SDOERR_WRONG_TOGGLEBIT; // abort: toggle bit not altered cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } if(length == 0) { // all data tranmitted? can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_NOERROR; } case CANERR_RX_EMPTY: // receiver empty: if(can_is_timeout()) { // time-out occurred? cop_error = SDOERR_PROTOCOL_TIMEOUT; // abort: time-out cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; } break; default: // other errors: cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = rc; } } while(rc != CANERR_NOERROR); t = t? 0x00 : 0x10; // alternate toggle bit! } }
static LONG sdo_expedited(BYTE node_id, WORD index, BYTE subindex, SHORT length, BYTE *data) { short n; // data length code short rc; // return value // --- Expedited SDO Download --- cop_buffer[0] = (BYTE)0x23; // client command specifier cop_buffer[0] |= (BYTE)((4 - length) << 2); cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex memset(&cop_buffer[4],0x00,4); // clear data buffer memcpy(&cop_buffer[4],data,length); // copy data bytes n = 8; // 8 bytes to transmit! // 1. Configure transmit message object for client SDO if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) { can_delete(CANBUF_TX); return cop_error; } // 2. Configure receive message object for server SDO if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 2. Transmit the client SDO message if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) { can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } // 3. Start timer for SDO time-out can_start_timer(cop_timeout); // 4. Wait until server message is received do { switch((rc = can_receive(CANBUF_RX, &n, cop_buffer))) { case CANERR_NOERROR: // confirmation: if(n != 8) { // 8 bytes received? cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_LENGTH; } if((cop_buffer[1] != LOBYTE(index)) || // multiplexor? index (LSB) (cop_buffer[2] != HIBYTE(index)) || // index (MSB) (cop_buffer[3] != (BYTE)(subindex))) { // subindex rc = COPERR_FORMAT; break; } if((cop_buffer[0] & 0xFF) == 0x80) { // SDO abort received? LOLOBYTE(cop_error) = cop_buffer[4]; // abort code (LSB) LOHIBYTE(cop_error) = cop_buffer[5]; // -"- HILOBYTE(cop_error) = cop_buffer[6]; // -"- HIHIBYTE(cop_error) = cop_buffer[7]; // abort code (MSB) // Return value is abort code! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error; } if((cop_buffer[0] & 0xFF) != 0x60) { // unknown command specifier? cop_error = SDOERR_UNKNOWN_SPECIFIER; // abort: unknown command specifier cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_FORMAT; } else { // success: data written! can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_NOERROR; } case CANERR_RX_EMPTY: // receiver empty: if(can_is_timeout()) { // time-out occurred? cop_error = SDOERR_PROTOCOL_TIMEOUT; // abort: time-out cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = COPERR_TIMEOUT; } break; default: // other errors: cop_error = SDOERR_GENERAL_ERROR; // abort: general error cop_buffer[0] = 0x80; // command specifier cop_buffer[1] = LOBYTE(index); // multiplexor: index (LSB) cop_buffer[2] = HIBYTE(index); // index (MSB) cop_buffer[3] = (BYTE)(subindex); // subindex cop_buffer[4] = LOLOBYTE(cop_error); // abort code (LSB) cop_buffer[5] = LOHIBYTE(cop_error); // -"- cop_buffer[6] = HILOBYTE(cop_error); // -"- cop_buffer[7] = HIHIBYTE(cop_error); // abort code (MSB) // Transmit SDO abort and return can_transmit(CANBUF_TX, 8, cop_buffer); can_delete(CANBUF_TX); can_delete(CANBUF_RX); return cop_error = rc; } } while(1); // "the torture never stops!" }
/** * Collect all non virtual methods and make all small methods candidates * for inlining. */ std::unordered_set<DexMethod*> SimpleInlinePass::gather_non_virtual_methods( Scope& scope, const std::unordered_set<DexType*>& no_inline) { // trace counter size_t all_methods = 0; size_t direct_methods = 0; size_t direct_no_code = 0; size_t non_virtual_no_code = 0; size_t clinit = 0; size_t init = 0; size_t static_methods = 0; size_t private_methods = 0; size_t dont_strip = 0; size_t no_inline_anno_count = 0; size_t non_virt_dont_strip = 0; size_t non_virt_methods = 0; // collect all non virtual methods (dmethods and vmethods) std::unordered_set<DexMethod*> methods; const auto can_inline_method = [&](DexMethod* meth, DexCode* code) { if (has_anno(type_class(meth->get_class()), no_inline) || has_anno(meth, no_inline)) { no_inline_anno_count++; return; } if (code->get_instructions().size() < SMALL_CODE_SIZE) { // always inline small methods even if they are not deletable inlinable.insert(meth); } else { if (!can_delete(meth)) { // never inline methods that cannot be deleted TRACE(SINL, 4, "cannot_delete: %s\n", SHOW(meth)); dont_strip++; } else { methods.insert(meth); } } }; walk_methods(scope, [&](DexMethod* method) { all_methods++; if (method->is_virtual()) return; auto code = method->get_code(); bool dont_inline = code == nullptr; direct_methods++; if (code == nullptr) direct_no_code++; if (is_constructor(method)) { (is_static(method)) ? clinit++ : init++; dont_inline = true; } else { (is_static(method)) ? static_methods++ : private_methods++; } if (dont_inline) return; can_inline_method(method, code); }); if (m_virtual_inline) { auto non_virtual = devirtualize(scope); non_virt_methods = non_virtual.size(); for (const auto& vmeth : non_virtual) { auto code = vmeth->get_code(); if (code == nullptr) { non_virtual_no_code++; continue; } can_inline_method(vmeth, code); } } TRACE(SINL, 2, "All methods count: %ld\n", all_methods); TRACE(SINL, 2, "Direct methods count: %ld\n", direct_methods); TRACE(SINL, 2, "Virtual methods count: %ld\n", all_methods - direct_methods); TRACE(SINL, 2, "Direct methods no code: %ld\n", direct_no_code); TRACE(SINL, 2, "Direct methods with code: %ld\n", direct_methods - direct_no_code); TRACE(SINL, 2, "Constructors with or without code: %ld\n", init); TRACE(SINL, 2, "Static constructors: %ld\n", clinit); TRACE(SINL, 2, "Static methods: %ld\n", static_methods); TRACE(SINL, 2, "Private methods: %ld\n", private_methods); TRACE(SINL, 2, "Virtual methods non virtual count: %ld\n", non_virt_methods); TRACE(SINL, 2, "Non virtual no code count: %ld\n", non_virtual_no_code); TRACE(SINL, 2, "Non virtual no strip count: %ld\n", non_virt_dont_strip); TRACE(SINL, 2, "Small methods: %ld\n", inlinable.size()); TRACE(SINL, 2, "Don't strip inlinable methods count: %ld\n", dont_strip); TRACE(SINL, 2, "Don't inline annotation count: %ld\n", no_inline_anno_count); return methods; }