static int proc_readdir(struct fs_dirent_s *dir) { FAR struct proc_dir_s *procdir; FAR const struct proc_node_s *node = NULL; FAR struct tcb_s *tcb; unsigned int index; irqstate_t flags; pid_t pid; int ret; DEBUGASSERT(dir != NULL && dir->u.procfs != NULL); procdir = dir->u.procfs; /* Have we reached the end of the directory */ index = procdir->base.index; if (index >= procdir->base.nentries) { /* We signal the end of the directory by returning the special * error -ENOENT */ finfo("Entry %d: End of directory\n", index); ret = -ENOENT; } /* No, we are not at the end of the directory */ else { /* Verify that the pid still refers to an active task/thread */ pid = procdir->pid; flags = enter_critical_section(); tcb = sched_gettcb(pid); leave_critical_section(flags); if (tcb == NULL) { ferr("ERROR: PID %d is no longer valid\n", (int)pid); return -ENOENT; } /* The TCB is still valid (or at least was when we entered this function) */ /* Handle the directory listing by the node type */ switch (procdir->node->node) { case PROC_LEVEL0: /* Top level directory */ DEBUGASSERT(procdir->base.level == 1); node = g_level0info[index]; break; case PROC_GROUP: /* Group sub-directory */ DEBUGASSERT(procdir->base.level == 2); node = g_groupinfo[index]; break; default: return -ENOENT; } /* Save the filename and file type */ dir->fd_dir.d_type = node->dtype; strncpy(dir->fd_dir.d_name, node->name, NAME_MAX+1); /* Set up the next directory entry offset. NOTE that we could use the * standard f_pos instead of our own private index. */ procdir->base.index = index + 1; ret = OK; } return ret; }
void WReqn(elem *e) { static int nest; if (!e) return; if (OTunary(e->Eoper)) { WROP(e->Eoper); if (OTbinary(e->E1->Eoper)) { nest++; ferr("("); WReqn(e->E1); ferr(")"); nest--; } else WReqn(e->E1); } else if (e->Eoper == OPcomma && !nest) { WReqn(e->E1); dbg_printf(";\n\t"); WReqn(e->E2); } else if (OTbinary(e->Eoper)) { if (OTbinary(e->E1->Eoper)) { nest++; ferr("("); WReqn(e->E1); ferr(")"); nest--; } else WReqn(e->E1); ferr(" "); WROP(e->Eoper); if (e->Eoper == OPstreq) dbg_printf("%ld",(long)type_size(e->ET)); ferr(" "); if (OTbinary(e->E2->Eoper)) { nest++; ferr("("); WReqn(e->E2); ferr(")"); nest--; } else WReqn(e->E2); } else { switch (e->Eoper) { case OPconst: switch (tybasic(e->Ety)) { case TYfloat: dbg_printf("%g <float> ",e->EV.Vfloat); break; case TYdouble: dbg_printf("%g ",e->EV.Vdouble); break; case TYldouble: dbg_printf("%Lg ",e->EV.Vldouble); break; case TYcent: case TYucent: dbg_printf("%lld+%lld ", e->EV.Vcent.msw, e->EV.Vcent.lsw); break; default: dbg_printf("%lld ",el_tolong(e)); break; } break; case OPrelconst: ferr("#"); /* FALL-THROUGH */ case OPvar: dbg_printf("%s",e->EV.sp.Vsym->Sident); if (e->EV.sp.Vsym->Ssymnum != -1) dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); if (e->Eoffset != 0) { if (sizeof(e->Eoffset) == 8) dbg_printf(".x%llx", e->Eoffset); else dbg_printf(".%ld",(long)e->Eoffset); } break; case OPasm: case OPstring: dbg_printf("\"%s\"",e->EV.ss.Vstring); if (e->EV.ss.Voffset) dbg_printf("+%ld",(long)e->EV.ss.Voffset); break; case OPmark: case OPgot: case OPframeptr: case OPhalt: WROP(e->Eoper); break; case OPstrthis: break; default: WROP(e->Eoper); assert(0); } } }
int pipecommon_open(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; FAR struct pipe_dev_s *dev = inode->i_private; int sval; int ret; DEBUGASSERT(dev != NULL); /* Make sure that we have exclusive access to the device structure. The * sem_wait() call should fail only if we are awakened by a signal. */ ret = sem_wait(&dev->d_bfsem); if (ret != OK) { ferr("ERROR: sem_wait failed: %d\n", get_errno()); DEBUGASSERT(get_errno() > 0); return -get_errno(); } /* If this the first reference on the device, then allocate the buffer. * In the case of policy 1, the buffer already be present when the pipe * is first opened. */ if (dev->d_refs == 0 && dev->d_buffer == NULL) { dev->d_buffer = (FAR uint8_t *)kmm_malloc(dev->d_bufsize); if (!dev->d_buffer) { (void)sem_post(&dev->d_bfsem); return -ENOMEM; } } /* Increment the reference count on the pipe instance */ dev->d_refs++; /* If opened for writing, increment the count of writers on the pipe instance */ if ((filep->f_oflags & O_WROK) != 0) { dev->d_nwriters++; /* If this this is the first writer, then the read semaphore indicates the * number of readers waiting for the first writer. Wake them all up. */ if (dev->d_nwriters == 1) { while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0) { sem_post(&dev->d_rdsem); } } } /* If opened for reading, increment the count of reader on on the pipe instance */ if ((filep->f_oflags & O_RDOK) != 0) { dev->d_nreaders++; } /* If opened for read-only, then wait for either (1) at least one writer * on the pipe (policy == 0), or (2) until there is buffered data to be * read (policy == 1). */ sched_lock(); (void)sem_post(&dev->d_bfsem); if ((filep->f_oflags & O_RDWR) == O_RDONLY && /* Read-only */ dev->d_nwriters < 1 && /* No writers on the pipe */ dev->d_wrndx == dev->d_rdndx) /* Buffer is empty */ { /* NOTE: d_rdsem is normally used when the read logic waits for more * data to be written. But until the first writer has opened the * pipe, the meaning is different: it is used prevent O_RDONLY open * calls from returning until there is at least one writer on the pipe. * This is required both by spec and also because it prevents * subsequent read() calls from returning end-of-file because there is * no writer on the pipe. */ ret = sem_wait(&dev->d_rdsem); if (ret != OK) { /* The sem_wait() call should fail only if we are awakened by * a signal. */ ferr("ERROR: sem_wait failed: %d\n", get_errno()); DEBUGASSERT(get_errno() > 0); ret = -get_errno(); /* Immediately close the pipe that we just opened */ (void)pipecommon_close(filep); } } sched_unlock(); return ret; }
static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, off_t startblock, size_t nblocks) { struct ftl_struct_s *dev = (struct ftl_struct_s *)priv; off_t alignedblock; off_t mask; off_t rwblock; off_t eraseblock; off_t offset; size_t remaining; size_t nxfrd; int nbytes; int ret; /* Get the aligned block. Here is is assumed: (1) The number of R/W blocks * per erase block is a power of 2, and (2) the erase begins with that same * alignment. */ mask = dev->blkper - 1; alignedblock = (startblock + mask) & ~mask; /* Handle partial erase blocks before the first unaligned block */ remaining = nblocks; if (alignedblock > startblock) { /* Check if the write is shorter than to the end of the erase block */ bool short_write = (remaining < (alignedblock - startblock)); /* Read the full erase block into the buffer */ rwblock = startblock & ~mask; nxfrd = MTD_BREAD(dev->mtd, rwblock, dev->blkper, dev->eblock); if (nxfrd != dev->blkper) { ferr("ERROR: Read erase block %d failed: %d\n", rwblock, nxfrd); return -EIO; } /* Then erase the erase block */ eraseblock = rwblock / dev->blkper; ret = MTD_ERASE(dev->mtd, eraseblock, 1); if (ret < 0) { ferr("ERROR: Erase block=%d failed: %d\n", eraseblock, ret); return ret; } /* Copy the user data at the end of the buffered erase block */ offset = (startblock & mask) * dev->geo.blocksize; if (short_write) { nbytes = remaining * dev->geo.blocksize; } else { nbytes = dev->geo.erasesize - offset; } finfo("Copy %d bytes into erase block=%d at offset=%d\n", nbytes, eraseblock, offset); memcpy(dev->eblock + offset, buffer, nbytes); /* And write the erase block back to flash */ nxfrd = MTD_BWRITE(dev->mtd, rwblock, dev->blkper, dev->eblock); if (nxfrd != dev->blkper) { ferr("ERROR: Write erase block %d failed: %d\n", rwblock, nxfrd); return -EIO; } /* Then update for amount written */ if (short_write) { remaining = 0; } else { remaining -= dev->blkper - (startblock & mask); } buffer += nbytes; } /* How handle full erase pages in the middle */ while (remaining >= dev->blkper) { /* Erase the erase block */ eraseblock = alignedblock / dev->blkper; ret = MTD_ERASE(dev->mtd, eraseblock, 1); if (ret < 0) { ferr("ERROR: Erase block=%d failed: %d\n", eraseblock, ret); return ret; } /* Write a full erase back to flash */ finfo("Write %d bytes into erase block=%d at offset=0\n", dev->geo.erasesize, alignedblock); nxfrd = MTD_BWRITE(dev->mtd, alignedblock, dev->blkper, buffer); if (nxfrd != dev->blkper) { ferr("ERROR: Write erase block %d failed: %d\n", alignedblock, nxfrd); return -EIO; } /* Then update for amount written */ alignedblock += dev->blkper; remaining -= dev->blkper; buffer += dev->geo.erasesize; } /* Finally, handle any partial blocks after the last full erase block */ if (remaining > 0) { /* Read the full erase block into the buffer */ nxfrd = MTD_BREAD(dev->mtd, alignedblock, dev->blkper, dev->eblock); if (nxfrd != dev->blkper) { ferr("ERROR: Read erase block %d failed: %d\n", alignedblock, nxfrd); return -EIO; } /* Then erase the erase block */ eraseblock = alignedblock / dev->blkper; ret = MTD_ERASE(dev->mtd, eraseblock, 1); if (ret < 0) { ferr("ERROR: Erase block=%d failed: %d\n", eraseblock, ret); return ret; } /* Copy the user data at the beginning the buffered erase block */ nbytes = remaining * dev->geo.blocksize; finfo("Copy %d bytes into erase block=%d at offset=0\n", nbytes, alignedblock); memcpy(dev->eblock, buffer, nbytes); /* And write the erase back to flash */ nxfrd = MTD_BWRITE(dev->mtd, alignedblock, dev->blkper, dev->eblock); if (nxfrd != dev->blkper) { ferr("ERROR: Write erase block %d failed: %d\n", alignedblock, nxfrd); return -EIO; } } return nblocks; }
int stm32_at24_automount(int minor) { FAR struct i2c_master_s *i2c; FAR struct mtd_dev_s *mtd; static bool initialized = false; int ret; /* Have we already initialized? */ if (!initialized) { /* No.. Get the I2C bus driver */ finfo("Initialize I2C%d\n", AT24_I2C_BUS); i2c = stm32_i2cbus_initialize(AT24_I2C_BUS); if (!i2c) { ferr("ERROR: Failed to initialize I2C%d\n", AT24_I2C_BUS); return -ENODEV; } /* Now bind the I2C interface to the AT24 I2C EEPROM driver */ finfo("Bind the AT24 EEPROM driver to I2C%d\n", AT24_I2C_BUS); mtd = at24c_initialize(i2c); if (!mtd) { ferr("ERROR: Failed to bind TWI%d to the AT24 EEPROM driver\n", AT24_I2C_BUS); return -ENODEV; } #if defined(CONFIG_STM32F103MINIMUM_AT24_FTL) /* And finally, use the FTL layer to wrap the MTD driver as a block driver */ finfo("Initialize the FTL layer to create /dev/mtdblock%d\n", AT24_MINOR); ret = ftl_initialize(AT24_MINOR, mtd); if (ret < 0) { ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret); return ret; } #elif defined(CONFIG_STM32F103MINIMUM_AT24_NXFFS) /* Initialize to provide NXFFS on the MTD interface */ finfo("Initialize the NXFFS file system\n"); ret = nxffs_initialize(mtd); if (ret < 0) { ferr("ERROR: NXFFS initialization failed: %d\n", ret); return ret; } /* Mount the file system at /mnt/at24 */ finfo("Mount the NXFFS file system at /dev/at24\n"); ret = mount(NULL, "/mnt/at24", "nxffs", 0, NULL); if (ret < 0) { ferr("ERROR: Failed to mount the NXFFS volume: %d\n", errno); return ret; } #endif /* Now we are initialized */ initialized = true; } return OK; }
static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) { FAR struct procfs_dir_priv_s *priv; FAR struct procfs_level0_s *level0; FAR struct tcb_s *tcb; FAR const char *name = NULL; unsigned int index; irqstate_t flags; pid_t pid; int ret = -ENOENT; DEBUGASSERT(mountpt && dir && dir->u.procfs); priv = dir->u.procfs; /* Are we reading the 1st directory level with dynamic PID and static * entries? */ if (priv->level == 0) { level0 = (FAR struct procfs_level0_s *)priv; /* Have we reached the end of the PID information */ index = priv->index; if (index >= priv->nentries) { /* We must report the next static entry ... no more PID entries. * skip any entries with wildcards in the first segment of the * directory name. */ while (index < priv->nentries + g_procfs_entrycount) { name = g_procfs_entries[index - priv->nentries].pathpattern; while (*name != '/' && *name != '\0') { if (*name == '*' || *name == '[' || *name == '?') { /* Wildcard found. Skip this entry */ index++; name = NULL; break; } name++; } /* Test if we skipped this entry */ if (name != NULL) { /* This entry is okay to report. Test if it has a duplicate * first level name as the one we just reported. This could * happen in the event of procfs_entry_s such as: * * fs/smartfs * fs/nfs * fs/nxffs */ name = g_procfs_entries[index - priv->nentries].pathpattern; if (!level0->lastlen || (strncmp(name, level0->lastread, level0->lastlen) != 0)) { /* Not a duplicate, return the first segment of this * entry */ break; } else { /* Skip this entry ... duplicate 1st level name found */ index++; } } } /* Test if we are at the end of the directory */ if (index >= priv->nentries + g_procfs_entrycount) { /* We signal the end of the directory by returning the special * error -ENOENT */ finfo("Entry %d: End of directory\n", index); ret = -ENOENT; } else { /* Report the next static entry */ level0->lastlen = strcspn(name, "/"); level0->lastread = name; strncpy(dir->fd_dir.d_name, name, level0->lastlen); dir->fd_dir.d_name[level0->lastlen] = '\0'; if (name[level0->lastlen] == '/') { dir->fd_dir.d_type = DTYPE_DIRECTORY; } else { dir->fd_dir.d_type = DTYPE_FILE; } /* Advance to next entry for the next read */ priv->index = index; ret = OK; } } #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS else { /* Verify that the pid still refers to an active task/thread */ pid = level0->pid[index]; flags = enter_critical_section(); tcb = sched_gettcb(pid); leave_critical_section(flags); if (!tcb) { ferr("ERROR: PID %d is no longer valid\n", (int)pid); return -ENOENT; } /* Save the filename=pid and file type=directory */ dir->fd_dir.d_type = DTYPE_DIRECTORY; snprintf(dir->fd_dir.d_name, NAME_MAX+1, "%d", (int)pid); /* Set up the next directory entry offset. NOTE that we could use the * standard f_pos instead of our own private index. */ level0->base.index = index + 1; ret = OK; } #endif /* CONFIG_FS_PROCFS_EXCLUDE_PROCESS */ } /* Are we reading an intermediate subdirectory? */ else if (priv->level > 0 && priv->procfsentry == NULL) { FAR struct procfs_level1_s *level1; level1 = (FAR struct procfs_level1_s *) priv; /* Test if this entry matches. We assume all entries of the same * subdirectory are listed in order in the procfs_entry array. */ if (strncmp(g_procfs_entries[level1->base.index].pathpattern, g_procfs_entries[level1->firstindex].pathpattern, level1->subdirlen) == 0) { /* This entry matches. Report the subdir entry */ name = &g_procfs_entries[level1->base.index].pathpattern[ level1->subdirlen + 1]; level1->lastlen = strcspn(name, "/"); level1->lastread = name; strncpy(dir->fd_dir.d_name, name, level1->lastlen); /* Some of the search entries contain '**' wildcards. When we * report the entry name, we must remove this wildcard search * specifier. */ while (dir->fd_dir.d_name[level1->lastlen - 1] == '*') { level1->lastlen--; } dir->fd_dir.d_name[level1->lastlen] = '\0'; if (name[level1->lastlen] == '/') { dir->fd_dir.d_type = DTYPE_DIRECTORY; } else { dir->fd_dir.d_type = DTYPE_FILE; } level1->base.index++; ret = OK; } else { /* No more entries in the subdirectory */ ret = -ENOENT; } } else { /* We are performing a directory search of one of the subdirectories * and we must let the handler perform the read. */ DEBUGASSERT(priv->procfsentry && priv->procfsentry->ops->readdir); ret = priv->procfsentry->ops->readdir(dir); } return ret; }
int nxffs_blockstats(FAR struct nxffs_volume_s *volume, FAR struct nxffs_blkstats_s *stats) { #ifndef CONFIG_NXFFS_NAND FAR uint8_t *bptr; /* Pointer to next block data */ int lblock; /* Logical block index */ #endif off_t ioblock; /* I/O block number */ int ret; /* Process each erase block */ memset(stats, 0, sizeof(struct nxffs_blkstats_s)); #ifndef CONFIG_NXFFS_NAND for (ioblock = 0; ioblock < volume->nblocks; ioblock += volume->blkper) { /* Read the full erase block */ ret = MTD_BREAD(volume->mtd, ioblock, volume->blkper, volume->pack); if (ret < volume->blkper) { ferr("ERROR: Failed to read erase block %d: %d\n", ioblock / volume->blkper, ret); return ret; } /* Then examine each logical block in the erase block */ for (bptr = volume->pack, lblock = 0; lblock < volume->blkper; bptr += volume->geo.blocksize, lblock++) { /* We read the block successfully, now check for errors tagged * in the NXFFS data. */ FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)bptr; /* Increment the total count of blocks examined */ stats->nblocks++; /* Collect statistics */ /* Check if this is a block that should be recognized by NXFFS */ if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0) { /* Nope.. block must not be formatted */ stats->nunformat++; } else if (blkhdr->state == BLOCK_STATE_BAD) { /* The block is marked as bad */ stats->nbad++; } else if (blkhdr->state == BLOCK_STATE_GOOD) { /* The block is marked as good */ stats-> ngood++; } else { /* The good/bad mark is not recognized. Let's call this * corrupt (vs. unformatted). */ stats->ncorrupt++; } } } finfo("Number blocks: %d\n", stats->nblocks); finfo(" Good blocks: %d\n", stats->ngood); finfo(" Bad blocks: %d\n", stats->nbad); finfo(" Unformatted blocks: %d\n", stats->nunformat); finfo(" Corrupt blocks: %d\n", stats->ncorrupt); #else for (ioblock = 0; ioblock < volume->nblocks; ioblock++) { /* Increment the total count of blocks examined */ stats->nblocks++; /* Read each logical block, one at a time. We could read all of the * blocks in the erase block into volume->pack at once. But this would * be a problem for NAND which may generate read errors due to bad ECC * on individual blocks. */ ret = MTD_BREAD(volume->mtd, ioblock, 1, volume->pack); if (ret < 1) { /* This should not happen at all on most kinds of FLASH. But a * bad read will happen normally with a NAND device that has * uncorrectable blocks. So, just for NAND, we keep the count * of unreadable blocks. */ ferr("ERROR: Failed to read block %d: %d\n", ioblock, ret); /* Increment the count of un-readable blocks */ stats->nbadread++; } else { /* We read the block successfully, now check for errors tagged * in the NXFFS data. */ FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)volume->pack; /* Collect statistics */ /* Check if this is a block that should be recognized by NXFFS */ if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0) { /* Nope.. block must not be formatted */ stats->nunformat++; } else if (blkhdr->state == BLOCK_STATE_BAD) { /* The block is marked as bad */ stats->nbad++; } else if (blkhdr->state == BLOCK_STATE_GOOD) { /* The block is marked as good */ stats-> ngood++; } else { /* The good/bad mark is not recognized. Let's call this * corrupt (vs. unformatted). */ stats->ncorrupt++; } } } finfo("Number blocks: %d\n", stats->nblocks); finfo(" Good blocks: %d\n", stats->ngood); finfo(" Bad blocks: %d\n", stats->nbad); finfo(" Unformatted blocks: %d\n", stats->nunformat); finfo(" Corrupt blocks: %d\n", stats->ncorrupt); finfo(" Unreadable blocks: %d\n", stats->nbadread); #endif return OK; }
FAR struct mtd_dev_s *blockmtd_initialize(FAR const char *path, size_t offset, size_t mtdlen, int16_t sectsize, int32_t erasesize) { FAR struct file_dev_s *priv; size_t nblocks; int mode; int ret; int fd; /* Create an instance of the FILE MTD device state structure */ priv = (FAR struct file_dev_s *)kmm_zalloc(sizeof(struct file_dev_s)); if (!priv) { ferr("ERROR: Failed to allocate the FILE MTD state structure\n"); return NULL; } /* Determine the file open mode */ mode = O_RDOK; #ifdef CONFIG_FS_WRITABLE mode |= O_WROK; #endif /* Try to open the file. NOTE that block devices will use a character * driver proxy. */ fd = open(path, mode); if (fd <0) { ferr("ERROR: Failed to open the FILE MTD file %s\n", path); kmm_free(priv); return NULL; } /* Detach the file descriptor from the open file */ ret = file_detach(fd, &priv->mtdfile); if (ret < 0) { ferr("ERROR: Failed to detail the FILE MTD file %s\n", path); close(fd); kmm_free(priv); return NULL; } /* Set the block size based on the provided sectsize parameter */ if (sectsize <= 0) { priv->blocksize = CONFIG_FILEMTD_BLOCKSIZE; } else { priv->blocksize = sectsize; } /* Set the erase size based on the provided erasesize parameter */ if (erasesize <= 0) { priv->erasesize = CONFIG_FILEMTD_ERASESIZE; } else { priv->erasesize = erasesize; } /* Force the size to be an even number of the erase block size */ nblocks = mtdlen / priv->erasesize; if (nblocks < 3) { ferr("ERROR: Need to provide at least three full erase block\n"); file_close_detached(&priv->mtdfile); kmm_free(priv); return NULL; } /* Perform initialization as necessary. (unsupported methods were * nullified by kmm_zalloc). */ priv->mtd.erase = filemtd_erase; priv->mtd.bread = filemtd_bread; priv->mtd.bwrite = filemtd_bwrite; priv->mtd.read = filemtd_byteread; #ifdef CONFIG_MTD_BYTE_WRITE priv->mtd.write = file_bytewrite; #endif priv->mtd.ioctl = filemtd_ioctl; priv->offset = offset; priv->nblocks = nblocks; #ifdef CONFIG_MTD_REGISTRATION /* Register the MTD with the procfs system if enabled */ mtd_register(&priv->mtd, "filemtd"); #endif return &priv->mtd; }
int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose) { #if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_FS) struct nxffs_blkinfo_s blkinfo; int ret; /* Get the volume geometry. (casting to uintptr_t first eliminates * complaints on some architectures where the sizeof long is different * from the size of a pointer). */ memset(&blkinfo, 0, sizeof(struct nxffs_blkinfo_s)); ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&blkinfo.geo)); if (ret < 0) { ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret); return ret; } /* Save the verbose output indication */ blkinfo.verbose = verbose; /* Allocate a buffer to hold one block */ blkinfo.buffer = (FAR uint8_t *)kmm_malloc(blkinfo.geo.blocksize); if (!blkinfo.buffer) { ferr("ERROR: Failed to allocate block cache\n"); return -ENOMEM; } /* Now read every block on the device */ syslog(LOG_NOTICE, "NXFFS Dump:\n"); syslog(LOG_NOTICE, g_hdrformat); blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize; for (blkinfo.block = 0, blkinfo.offset = 0; blkinfo.block < blkinfo.nblocks; blkinfo.block++, blkinfo.offset += blkinfo.geo.blocksize) { /* Read the next block */ ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer); if (ret < 0) { #ifndef CONFIG_NXFFS_NAND /* Read errors are fatal */ ferr("ERROR: Failed to read block %d\n", blkinfo.block); kmm_free(blkinfo.buffer); return ret; #else /* A read error is probably fatal on all media but NAND. * On NAND, the read error probably just signifies a block * with an uncorrectable ECC failure. So, to handle NAND, * just report the read error and continue. */ syslog(LOG_NOTICE, g_format, blkinfo.block, 0, "BLOCK", "RD FAIL", blkinfo.geo.blocksize); #endif } else { /* Analyze the block that we just read */ nxffs_analyze(&blkinfo); } } syslog(LOG_NOTICE, "%d blocks analyzed\n", blkinfo.nblocks); kmm_free(blkinfo.buffer); return OK; #else return -ENOSYS; #endif }
void WReqn(elem *e) { static int nest; if (!e) return; if (OTunary(e->Eoper)) { WROP(e->Eoper); if (OTbinary(e->E1->Eoper)) { nest++; ferr("("); WReqn(e->E1); ferr(")"); nest--; } else WReqn(e->E1); } else if (e->Eoper == OPcomma && !nest) { WReqn(e->E1); dbg_printf(";\n\t"); WReqn(e->E2); } else if (OTbinary(e->Eoper)) { if (OTbinary(e->E1->Eoper)) { nest++; ferr("("); WReqn(e->E1); ferr(")"); nest--; } else WReqn(e->E1); ferr(" "); WROP(e->Eoper); if (e->Eoper == OPstreq) dbg_printf("%ld",e->Enumbytes); ferr(" "); if (OTbinary(e->E2->Eoper)) { nest++; ferr("("); WReqn(e->E2); ferr(")"); nest--; } else WReqn(e->E2); } else { switch (e->Eoper) { case OPconst: switch (tybasic(e->Ety)) { case TYfloat: dbg_printf("%g <float> ",e->EV.Vfloat); break; case TYdouble: dbg_printf("%g ",e->EV.Vdouble); break; default: dbg_printf("%lld ",el_tolong(e)); break; } break; case OPrelconst: ferr("#"); /* FALL-THROUGH */ case OPvar: dbg_printf("%s",e->EV.sp.Vsym->Sident); if (e->EV.sp.Vsym->Ssymnum != -1) dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); if (e->Eoffset != 0) dbg_printf(".%ld",e->Eoffset); break; case OPasm: #if TARGET_MAC if (e->Eflags & EFsmasm) { if (e->EV.mac.Vasmdat[1]) dbg_printf("\"%c%c\"",e->EV.mac.Vasmdat[0],e->EV.mac.Vasmdat[1]); else dbg_printf("\"%c\"",e->EV.mac.Vasmdat[0]); break; }; #endif case OPstring: dbg_printf("\"%s\"",e->EV.ss.Vstring); if (e->EV.ss.Voffset) dbg_printf("+%ld",e->EV.ss.Voffset); break; case OPmark: case OPgot: case OPframeptr: WROP(e->Eoper); break; case OPstrthis: break; default: WROP(e->Eoper); assert(0); } } }
static ssize_t filemtd_write(FAR struct file_dev_s *priv, size_t offset, FAR const void *src, size_t len) { FAR const uint8_t *pin = (FAR const uint8_t *)src; FAR uint8_t *pout; char buf[128]; int buflen = 0; uint8_t oldvalue; uint8_t srcvalue; uint8_t newvalue; size_t seekpos; /* Set the starting location in the file */ seekpos = priv->offset + offset; while (len-- > 0) { if (buflen == 0) { /* Read more data from the file */ file_seek(&priv->mtdfile, seekpos, SEEK_SET); buflen = file_read(&priv->mtdfile, buf, sizeof(buf)); pout = (FAR uint8_t *) buf; } /* Get the source and destination values */ oldvalue = *pout; srcvalue = *pin++; /* Get the new destination value, accounting for bits that cannot be * changes because they are not in the erased state. */ #if CONFIG_FILEMTD_ERASESTATE == 0xff newvalue = oldvalue & srcvalue; /* We can only clear bits */ #else /* CONFIG_FILEMTD_ERASESTATE == 0x00 */ newvalue = oldvalue | srcvalue; /* We can only set bits */ #endif /* Report any attempt to change the value of bits that are not in the * erased state. */ #ifdef CONFIG_DEBUG_FEATURES if (newvalue != srcvalue) { ferr("ERROR: Bad write: source=%02x dest=%02x result=%02x\n", srcvalue, oldvalue, newvalue); } #endif /* Write the modified value to simulated FLASH */ *pout++ = newvalue; buflen--; /* If our buffer is full, then seek back to beginning of * the file and write the buffer contents */ if (buflen == 0) { file_seek(&priv->mtdfile, seekpos, SEEK_SET); (void)file_write(&priv->mtdfile, buf, sizeof(buf)); seekpos += sizeof(buf); } } /* Write remaining bytes */ if (buflen != 0) { file_seek(&priv->mtdfile, seekpos, SEEK_SET); (void)file_write(&priv->mtdfile, buf, sizeof(buf)); } return len; }
static off_t mtdconfig_consolidate(FAR struct mtdconfig_struct_s *dev) { off_t src_block, dst_block; off_t src_offset, dst_offset; uint16_t blkper, x, bytes, bytes_left_in_block; struct mtdconfig_header_s hdr; int ret; uint8_t sig[CONFIGDATA_BLOCK_HDR_SIZE]; uint8_t *pBuf; /* Prepare to copy block 0 to the last block (erase blocks) */ src_block = 0; dst_block = dev->neraseblocks - 1; /* Ensure the last block is erased */ MTD_ERASE(dev->mtd, dst_block, 1); blkper = dev->erasesize / dev->blocksize; dst_block *= blkper; /* Convert to read/write blocks */ /* Allocate a small buffer for moving data */ pBuf = (uint8_t *)kmm_malloc(dev->blocksize); if (pBuf == NULL) { return 0; } /* Now copy block zero to last block */ for (x = 0; x < blkper; x++) { ret = MTD_BREAD(dev->mtd, src_block++, 1, dev->buffer); if (ret < 0) { /* I/O Error! */ goto errout; } ret = MTD_BWRITE(dev->mtd, dst_block++, 1, dev->buffer); if (ret < 0) { /* I/O Error! */ goto errout; } } /* Erase block zero and write a format signature. */ MTD_ERASE(dev->mtd, 0, 1); sig[0] = 'C'; sig[1] = 'D'; sig[2] = CONFIGDATA_FORMAT_VERSION; ret = mtdconfig_writebytes(dev, 0, sig, sizeof(sig)); if (ret != sizeof(sig)) { /* Cannot write even the signature. */ ret = -EIO; goto errout; } /* Now consolidate entries. */ src_block = 1; dst_block = 0; src_offset = src_block * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; dst_offset = CONFIGDATA_BLOCK_HDR_SIZE; while (src_block < dev->neraseblocks) { /* Scan all headers and move them to the src_offset */ retry_relocate: bytes = MTD_READ(dev->mtd, src_offset, sizeof(hdr), (uint8_t *) &hdr); if (bytes != sizeof(hdr)) { /* I/O Error! */ ret = -EIO; goto errout; } if (hdr.flags == MTD_ERASED_FLAGS) { /* Test if the source entry is active or if we are at the end * of data for this erase block. */ if (hdr.id == MTD_ERASED_ID) { /* No more data in this erase block. Advance to the * next one. */ src_offset = (src_block + 1) * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; } else { /* Test if this entry will fit in the current destination block */ bytes_left_in_block = (dst_block + 1) * dev->erasesize - dst_offset; if (hdr.len + sizeof(hdr) > bytes_left_in_block) { /* Item doesn't fit in the block. Advance to the next one */ /* Update control variables */ dst_block++; dst_offset = dst_block * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; DEBUGASSERT(dst_block != src_block); /* Retry the relocate */ goto retry_relocate; } /* Copy this entry to the destination */ ret = mtdconfig_writebytes(dev, dst_offset, (uint8_t *) &hdr, sizeof(hdr)); if (ret != sizeof(hdr)) { /* I/O Error! */ ret = -EIO; goto errout; } src_offset += sizeof(hdr); dst_offset += sizeof(hdr); /* Now copy the data */ while (hdr.len) { bytes = hdr.len; if (bytes > dev->blocksize) { bytes = dev->blocksize; } /* Move the data. */ ret = mtdconfig_readbytes(dev, src_offset, pBuf, bytes); if (ret != OK) { /* I/O Error! */ ret = -EIO; goto errout; } ret = mtdconfig_writebytes(dev, dst_offset, pBuf, bytes); if (ret != bytes) { /* I/O Error! */ ret = -EIO; goto errout; } /* Update control variables */ hdr.len -= bytes; src_offset += bytes; dst_offset += bytes; } } } else { /* This item has been released. Skip it! */ src_offset += sizeof(hdr) + hdr.len; if (src_offset + sizeof(hdr) >= (src_block + 1) * dev->erasesize || src_offset == (src_block + 1) * dev->erasesize) { /* No room left at end of source block */ src_offset = (src_block + 1) * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; } } /* Test if we are out of space in the src block */ if (src_offset + sizeof(hdr) >= (src_block + 1) * dev->erasesize) { /* No room at end of src block for another header. Go to next * source block. */ src_offset = (src_block + 1) * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; } /* Test if we advanced to the next block. If we did, then erase the * old block. */ if (src_block != src_offset / dev->erasesize) { /* Erase the block ... we have emptied it */ MTD_ERASE(dev->mtd, src_block, 1); src_block++; } /* Test if we are out of space in the dst block */ if (dst_offset + sizeof(hdr) >= (dst_block + 1) * dev->erasesize) { /* No room at end of dst block for another header. Go to next block. */ dst_block++; dst_offset = dst_block * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; DEBUGASSERT(dst_block != src_block); } } kmm_free(pBuf); return dst_offset; errout: kmm_free(pBuf); ferr("ERROR: fail consolidate: %d\n", ret); return 0; }
static off_t mtdconfig_ramconsolidate(FAR struct mtdconfig_struct_s *dev) { FAR uint8_t *pBuf; FAR struct mtdconfig_header_s *phdr; struct mtdconfig_header_s hdr; uint16_t src_block = 0, dst_block = 0, blkper; off_t dst_offset = CONFIGDATA_BLOCK_HDR_SIZE; off_t src_offset = CONFIGDATA_BLOCK_HDR_SIZE; off_t bytes_left_in_block; uint8_t sig[CONFIGDATA_BLOCK_HDR_SIZE]; int ret; /* Allocate a consolidation buffer */ pBuf = (uint8_t *)kmm_malloc(dev->erasesize); if (pBuf == NULL) { /* Unable to allocate buffer, can't consolidate! */ return 0; } /* Loop for all blocks and consolidate them */ blkper = dev->erasesize / dev->blocksize; while (src_block < dev->neraseblocks) { /* Point to beginning of pBuf and read the next erase block */ ret = MTD_BREAD(dev->mtd, src_block * blkper, blkper, pBuf); if (ret < 0) { /* Error doing block read */ goto errout; } /* Now erase the block */ ret = MTD_ERASE(dev->mtd, src_block, 1); if (ret < 0) { /* Error erasing the block */ goto errout; } /* If this is block zero, then write a format signature */ if (src_block == 0) { sig[0] = 'C'; sig[1] = 'D'; sig[2] = CONFIGDATA_FORMAT_VERSION; ret = mtdconfig_writebytes(dev, 0, sig, sizeof(sig)); if (ret != sizeof(sig)) { /* Cannot write even the signature. */ ret = -EIO; goto errout; } } /* Copy active items back to the MTD device. */ while (src_offset < dev->erasesize) { phdr = (FAR struct mtdconfig_header_s *) &pBuf[src_offset]; if (phdr->id == MTD_ERASED_ID) { /* No more data in this erase block. */ src_offset = dev->erasesize; continue; } if (phdr->flags == MTD_ERASED_FLAGS) { /* This is an active entry. Copy it. Check if it * fits in the current destination block. */ bytes_left_in_block = (dst_block + 1) * dev->erasesize - dst_offset; if (bytes_left_in_block < sizeof(*phdr) + phdr->len) { /* Item won't fit in the destination block. Move to * the next block. */ dst_block++; dst_offset = dst_block * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; /* Test for program bug. We shouldn't ever overflow * even if no entries were inactive. */ DEBUGASSERT(dst_block != dev->neraseblocks); } /* Now write the item to the current dst_offset location. */ ret = mtdconfig_writebytes(dev, dst_offset, (uint8_t *) phdr, sizeof(hdr)); if (ret != sizeof(hdr)) { /* I/O Error! */ ret = -EIO; goto errout; } dst_offset += sizeof(hdr); ret = mtdconfig_writebytes(dev, dst_offset, &pBuf[src_offset + sizeof(hdr)], phdr->len); if (ret != phdr->len) { /* I/O Error! */ ret = -EIO; goto errout; } dst_offset += phdr->len; /* Test if enough space in dst block for another header */ if (dst_offset + sizeof(hdr) >= (dst_block + 1) * dev->erasesize || dst_offset == (dst_block + 1) * dev->erasesize) { dst_block++; dst_offset = dst_block * dev->erasesize + CONFIGDATA_BLOCK_HDR_SIZE; } } /* Increment past the current source item */ src_offset += sizeof(hdr) + phdr->len; if (src_offset + sizeof(hdr) > dev->erasesize) { src_offset = dev->erasesize; } DEBUGASSERT(src_offset <= dev->erasesize); } /* Increment to next source block */ src_block++; src_offset = CONFIGDATA_BLOCK_HDR_SIZE; } kmm_free(pBuf); return dst_offset; errout: kmm_free(pBuf); ferr("ERROR: fail ram consolidate: %d\n", ret); return 0; }
static int proc_stat(const char *relpath, struct stat *buf) { FAR const struct proc_node_s *node; FAR struct tcb_s *tcb; unsigned long tmp; FAR char *ptr; irqstate_t flags; pid_t pid; /* Two path forms are accepted: * * "<pid>" - If <pid> refers to a currently active task/thread, then it * is a directory * "<pid>/<node>" - If <node> is a recognized node then, then it * is a file or directory. */ ptr = NULL; if (strncmp(relpath, "self", 4) == 0) { tmp = (unsigned long)getpid(); /* Get the PID of the calling task */ ptr = (FAR char *)relpath + 4; /* Discard const */ } else { tmp = strtoul(relpath, &ptr, 10); /* Extract the PID from path */ } if (ptr == NULL) { ferr("ERROR: Invalid path \"%s\"\n", relpath); return -ENOENT; } /* A valid PID would be in the range of 0-32767 (0 is reserved for the * IDLE thread). */ if (tmp >= 32768) { ferr("ERROR: Invalid PID %ld\n", tmp); return -ENOENT; } /* Now verify that a task with this task/thread ID exists */ pid = (pid_t)tmp; flags = enter_critical_section(); tcb = sched_gettcb(pid); leave_critical_section(flags); if (tcb == NULL) { ferr("ERROR: PID %d is no longer valid\n", (int)pid); return -ENOENT; } /* Was the <pid> the final element of the path? */ memset(buf, 0, sizeof(struct stat)); if (*ptr == '\0' || strcmp(ptr, "/") == 0) { /* Yes ... It's a read-only directory */ buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } /* Verify that the process ID is followed by valid path segment delimiter */ else if (*ptr != '/') { /* We are required to return -ENOENT all all invalid paths */ ferr("ERROR: Bad delimiter '%c' in relpath '%s'\n", *ptr, relpath); return -ENOENT; } else { /* Otherwise, the second segment of the relpath should be a well * known node of the task/thread directory structure. */ /* Skip over the path segment delimiter */ ptr++; /* Lookup the well-known node associated with the relative path. */ node = proc_findnode(ptr); if (node == NULL) { ferr("ERROR: Invalid path \"%s\"\n", relpath); return -ENOENT; } /* If the node exists, it is the name for a read-only file or * directory. */ if (node->dtype == DTYPE_FILE) { buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; } else { buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } } return OK; }
int board_app_initialize(uintptr_t arg) { int ret; #ifdef CONFIG_FS_PROCFS /* Mount the procfs file system */ ret = mount(NULL, STM32_PROCFS_MOUNTPOINT, "procfs", 0, NULL); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to mount procfs at %s: %d\n", STM32_PROCFS_MOUNTPOINT, ret); } #endif #if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) /* Register the LED driver */ ret = userled_lower_initialize(LED_DRIVER_PATH); if (ret < 0) { syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret); } #endif #ifdef CONFIG_ADC /* Initialize ADC and register the ADC driver. */ ret = stm32_adc_setup(); if (ret < 0) { syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret); } #endif #ifdef CONFIG_STM32F7_BBSRAM /* Initialize battery-backed RAM */ (void)stm32_bbsram_int(); #endif #if defined(CONFIG_FAT_DMAMEMORY) if (stm32_dma_alloc_init() < 0) { syslog(LOG_ERR, "DMA alloc FAILED"); } #endif #if defined(CONFIG_NUCLEO_SPI_TEST) /* Create SPI interfaces */ ret = stm32_spidev_bus_test(); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI interfaces: %d\n", ret); return ret; } #endif #if defined(CONFIG_MMCSD) /* Configure SDIO */ /* Initialize the SDIO block driver */ ret = stm32_sdio_initialize(); if (ret != OK) { ferr("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); return ret; } #endif UNUSED(ret); return OK; }
// Tidy up before exiting by saving label dump int ACME_finalize(int exit_code) { FILE* fd; if(labeldump_filename) { #if defined(USE_FOPEN_S) errno_t err = fopen_s(&fd,labeldump_filename, FILE_WRITETEXT); if(ferr(fd,err)) { #else fd = fopen(labeldump_filename, FILE_WRITETEXT); if(fd) { #endif Label_dump_all(fd); fclose(fd); } else { fprintf(stderr, "Error: Cannot open label dump file \"%s\".\n", labeldump_filename); exit_code = EXIT_FAILURE; } } if(vicelabeldump_filename) { #if defined(USE_FOPEN_S) errno_t err = fopen_s(&fd,vicelabeldump_filename, FILE_WRITETEXT); if(ferr(fd,err)) { #else fd = fopen(vicelabeldump_filename, FILE_WRITETEXT); if(fd) { #endif Label_dump_all_vice(fd); fclose(fd); } else { fprintf(stderr, "Error: Cannot open label dump file \"%s\".\n", vicelabeldump_filename); exit_code = EXIT_FAILURE; } } return(exit_code); } // Save output file static void save_output_file(void) { FILE* fd; #if defined(USE_FOPEN_S) errno_t err; #endif // if no output file chosen, tell user and do nothing if(output_filename == NULL) { fputs("No output file specified (use the \"-o\" option or the \"!to\" pseudo opcode).", stderr); return; } #if defined(USE_FOPEN_S) err = fopen_s(&fd,output_filename, FILE_WRITETEXT); if((fd == NULL) | (err != NULL)) { #else fd = fopen(output_filename, FILE_WRITEBINARY); if(fd == NULL) { #endif fprintf(stderr, "Error: Cannot open output file \"%s\".\n", output_filename); return; } Output_save_file(fd); fclose(fd); } // Perform a single pass. Returns number of "NeedValue" type errors. static int perform_pass(void) { FILE* fd; int i; // call modules' "pass init" functions CPU_passinit(default_cpu);// set default cpu values (PC undefined) Output_passinit(start_addr);// call after CPU_passinit(), to define PC Encoding_passinit(); // set default encoding Section_passinit(); // set initial zone (untitled) // init variables pass_undefined_count = 0; // no "NeedValue" errors yet pass_real_errors = 0; // no real errors yet // Process toplevel files for(i = 0; i<toplevel_src_count; i++) { #if defined(USE_FOPEN_S) errno_t err = fopen_s(&fd,toplevel_sources[i], FILE_READBINARY); if(ferr(fd,err)) #else fd = fopen(toplevel_sources[i], FILE_READBINARY); if(fd) #endif Parse_and_close_file(fd, toplevel_sources[i]); else { fprintf(stderr, "Error: Cannot open toplevel file \"%s\".\n", toplevel_sources[i]); pass_real_errors++; } } if(pass_real_errors) exit(ACME_finalize(EXIT_FAILURE)); else Output_end_segment(); return(pass_undefined_count); } // do passes until done (or errors occured). Return whether output is ready. static bool do_actual_work(void) { int undefined_prev, // "NeedValue" errors of previous pass undefined_curr; // "NeedValue" errors of current pass if(Process_verbosity > 1) puts("First pass."); pass_count = 0; undefined_curr = perform_pass(); // First pass // now pretend there has been a pass before the first one undefined_prev = undefined_curr + 1; // As long as the number of "NeedValue" errors is decreasing but // non-zero, keep doing passes. while(undefined_curr && (undefined_curr < undefined_prev)) { pass_count++; undefined_prev = undefined_curr; if(Process_verbosity > 1) puts("Further pass."); undefined_curr = perform_pass(); } // If still errors (unsolvable by doing further passes), // perform additional pass to find and show them if(undefined_curr == 0) return(TRUE); if(Process_verbosity > 1) puts("Further pass needed to find error."); ALU_throw_errors(); // activate error output (CAUTION - one-way!) pass_count++; perform_pass(); // perform pass, but now show "value undefined" return(FALSE); }
static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, FAR struct fs_dirent_s *dir) { FAR struct procfs_level0_s *level0; FAR struct procfs_dir_priv_s *dirpriv; FAR void *priv = NULL; irqstate_t flags; finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL"); DEBUGASSERT(mountpt && relpath && dir && !dir->u.procfs); /* The relative must be either: * * "" - The top level directory of task/thread IDs * "<pid>" - The sub-directory of task/thread attributes */ if (!relpath || relpath[0] == '\0') { /* The path refers to the top level directory. Allocate the level0 * dirent structure. */ level0 = (FAR struct procfs_level0_s *) kmm_zalloc(sizeof(struct procfs_level0_s)); if (!level0) { ferr("ERROR: Failed to allocate the level0 directory structure\n"); return -ENOMEM; } /* Take a snapshot of all currently active tasks. Any new tasks * added between the opendir() and closedir() call will not be * visible. * * NOTE that interrupts must be disabled throughout the traversal. */ #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS flags = enter_critical_section(); sched_foreach(procfs_enum, level0); leave_critical_section(flags); #else level0->base.index = 0; level0->base.nentries = 0; #endif /* Initialize lastread entries */ level0->lastread = ""; level0->lastlen = 0; level0->base.procfsentry = NULL; priv = (FAR void *)level0; } else { int x, ret; int len = strlen(relpath); /* Search the static array of procfs_entries */ for (x = 0; x < g_procfs_entrycount; x++) { /* Test if the path matches this entry's specification */ if (match(g_procfs_entries[x].pathpattern, relpath)) { /* Match found! Call the handler's opendir routine. If successful, * this opendir routine will create an entry derived from struct * procfs_dir_priv_s as dir->u.procfs. */ DEBUGASSERT(g_procfs_entries[x].ops && g_procfs_entries[x].ops->opendir); ret = g_procfs_entries[x].ops->opendir(relpath, dir); if (ret == OK) { DEBUGASSERT(dir->u.procfs); /* Set the procfs_entry handler */ dirpriv = (FAR struct procfs_dir_priv_s *)dir->u.procfs; dirpriv->procfsentry = &g_procfs_entries[x]; } return ret; } /* Test for a sub-string match (e.g. "ls /proc/fs") */ else if (strncmp(g_procfs_entries[x].pathpattern, relpath, len) == 0) { FAR struct procfs_level1_s *level1; /* Doing an intermediate directory search */ /* The path refers to the top level directory. Allocate the level1 * dirent structure. */ level1 = (FAR struct procfs_level1_s *) kmm_zalloc(sizeof(struct procfs_level1_s)); if (!level1) { ferr("ERROR: Failed to allocate the level0 directory structure\n"); return -ENOMEM; } level1->base.level = 1; level1->base.index = x; level1->firstindex = x; level1->subdirlen = len; level1->lastread = ""; level1->lastlen = 0; level1->base.procfsentry = NULL; priv = (FAR void *)level1; break; } } } dir->u.procfs = priv; return OK; }
int main(int argc, char** argv){ if(argc==1)usage(help_str); for(filenum=0;filenum<argc;++filenum)if(unlink(argv[filenum])!=0)ferr(); _exit(0); }
int onfi_read(uintptr_t cmdaddr, uintptr_t addraddr, uintptr_t dataaddr, FAR struct onfi_pgparam_s *onfi) { uint8_t parmtab[ONFI_PARAM_TABLE_SIZE]; int i; finfo("cmdaddr=%08x addraddr=%08x dataaddr=%08x\n", (int)cmdaddr, (int)addraddr, (int)dataaddr); if (!onfi_compatible(cmdaddr, addraddr, dataaddr)) { ferr("ERROR: No ONFI compatible device detected\n"); return -ENODEV; } /* Initialize the ONFI parameter table */ memset(parmtab, 0xff, ONFI_PARAM_TABLE_SIZE); /* Perform Read Parameter Page command */ WRITE_NAND_COMMAND(NAND_CMD_READ_PARAM_PAGE, cmdaddr); WRITE_NAND_ADDRESS(0x0, addraddr); /* Wait NF ready */ onfi_readstatus(cmdaddr, dataaddr); /* Re-enable data output mode required after Read Status command */ WRITE_NAND_COMMAND(NAND_CMD_READ0, cmdaddr); /* Read the parameter table */ for (i = 0; i < ONFI_PARAM_TABLE_SIZE; i++) { parmtab[i] = READ_NAND(dataaddr); } for (i = 0; i < ONFI_PARAM_TABLE_SIZE; i++) { if (parmtab[i] != 0xff) { break; } } if (i == ONFI_PARAM_TABLE_SIZE) { ferr("ERROR: Failed to read ONFI parameter table\n"); return -EIO; } /* JEDEC manufacturer ID */ onfi->manufacturer = *(FAR uint8_t *)(parmtab + 64); /* Bus width */ onfi->buswidth = (*(FAR uint8_t *)(parmtab + 6)) & 0x01; /* Get number of data bytes per page (bytes 80-83 in the param table) */ onfi->pagesize = *(FAR uint32_t *)(FAR void *)(parmtab + 80); /* Get number of spare bytes per page (bytes 84-85 in the param table) */ onfi->sparesize = *(FAR uint16_t *)(FAR void *)(parmtab + 84); /* Number of pages per block. */ onfi->pagesperblock = *(FAR uint32_t *)(FAR void *)(parmtab + 92); /* Number of blocks per logical unit (LUN). */ onfi->blocksperlun = *(FAR uint32_t *)(FAR void *)(parmtab + 96); /* Number of logical units. */ onfi->luns = *(FAR uint8_t *)(parmtab + 100); /* Number of bits of ECC correction */ onfi->eccsize = *(FAR uint8_t *)(parmtab + 112); /* Device model */ onfi->model = *(FAR uint8_t *)(parmtab + 49); finfo("Returning:\n"); finfo(" manufacturer: 0x%02x\n", onfi->manufacturer); finfo(" buswidth: %d\n", onfi->buswidth); finfo(" luns: %d\n", onfi->luns); finfo(" eccsize: %d\n", onfi->eccsize); finfo(" model: 0x%02s\n", onfi->model); finfo(" sparesize: %d\n", onfi->sparesize); finfo(" pagesperblock: %d\n", onfi->pagesperblock); finfo(" blocksperlun: %d\n", onfi->blocksperlun); finfo(" pagesize: %d\n", onfi->pagesize); return OK; }
int board_app_initialize(uintptr_t arg) { #if defined(CONFIG_STM32_SPI4) FAR struct spi_dev_s *spi; FAR struct mtd_dev_s *mtd; FAR struct mtd_geometry_s geo; #endif #if defined(CONFIG_MTD_PARTITION_NAMES) FAR const char *partname = CONFIG_STM32F429I_DISCO_FLASH_PART_NAMES; #endif #if defined(CONFIG_MTD) && defined(CONFIG_MTD_SST25XX) int ret; #elif defined(HAVE_USBHOST) || defined(HAVE_USBMONITOR) int ret; #endif /* Configure SPI-based devices */ #ifdef CONFIG_STM32_SPI4 /* Get the SPI port */ syslog(LOG_INFO, "Initializing SPI port 4\n"); spi = stm32_spibus_initialize(4); if (!spi) { syslog(LOG_ERR, "ERROR: Failed to initialize SPI port 4\n"); return -ENODEV; } syslog(LOG_INFO, "Successfully initialized SPI port 4\n"); /* Now bind the SPI interface to the SST25F064 SPI FLASH driver. This * is a FLASH device that has been added external to the board (i.e. * the board does not ship from STM with any on-board FLASH. */ #if defined(CONFIG_MTD) && defined(CONFIG_MTD_SST25XX) syslog(LOG_INFO, "Bind SPI to the SPI flash driver\n"); mtd = sst25xx_initialize(spi); if (!mtd) { syslog(LOG_ERR, "ERROR: Failed to bind SPI port 4 to the SPI FLASH driver\n"); } else { syslog(LOG_INFO, "Successfully bound SPI port 4 to the SPI FLASH driver\n"); /* Get the geometry of the FLASH device */ ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo)); if (ret < 0) { ferr("ERROR: mtd->ioctl failed: %d\n", ret); return ret; } #ifdef CONFIG_STM32F429I_DISCO_FLASH_PART { int partno; int partsize; int partoffset; int partszbytes; int erasesize; const char *partstring = CONFIG_STM32F429I_DISCO_FLASH_PART_LIST; const char *ptr; FAR struct mtd_dev_s *mtd_part; char partref[4]; /* Now create a partition on the FLASH device */ partno = 0; ptr = partstring; partoffset = 0; /* Get the Flash erase size */ erasesize = geo.erasesize; while (*ptr != '\0') { /* Get the partition size */ partsize = atoi(ptr); partszbytes = (partsize << 10); /* partsize is defined in KB */ /* Check if partition size is bigger then erase block */ if (partszbytes < erasesize) { ferr("ERROR: Partition size is lesser than erasesize!\n"); return -1; } /* Check if partition size is multiple of erase block */ if ((partszbytes % erasesize) != 0) { ferr("ERROR: Partition size is not multiple of erasesize!\n"); return -1; } mtd_part = mtd_partition(mtd, partoffset, partszbytes / erasesize); partoffset += partszbytes / erasesize; #ifdef CONFIG_STM32F429I_DISCO_FLASH_CONFIG_PART /* Test if this is the config partition */ if (CONFIG_STM32F429I_DISCO_FLASH_CONFIG_PART_NUMBER == partno) { /* Register the partition as the config device */ mtdconfig_register(mtd_part); } else #endif { /* Now initialize a SMART Flash block device and bind it * to the MTD device. */ #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) sprintf(partref, "p%d", partno); smart_initialize(CONFIG_STM32F429I_DISCO_FLASH_MINOR, mtd_part, partref); #endif } #if defined(CONFIG_MTD_PARTITION_NAMES) /* Set the partition name */ if (mtd_part == NULL) { ferr("ERROR: failed to create partition %s\n", partname); return -1; } mtd_setpartitionname(mtd_part, partname); /* Now skip to next name. We don't need to split the string here * because the MTD partition logic will only display names up to * the comma, thus allowing us to use a single static name * in the code. */ while (*partname != ',' && *partname != '\0') { /* Skip to next ',' */ partname++; } if (*partname == ',') { partname++; } #endif /* Update the pointer to point to the next size in the list */ while ((*ptr >= '0') && (*ptr <= '9')) { ptr++; } if (*ptr == ',') { ptr++; } /* Increment the part number */ partno++; } } #else /* CONFIG_STM32F429I_DISCO_FLASH_PART */ /* Configure the device with no partition support */ smart_initialize(CONFIG_STM32F429I_DISCO_FLASH_MINOR, mtd, NULL); #endif /* CONFIG_STM32F429I_DISCO_FLASH_PART */ } #endif /* CONFIG_MTD */ #endif /* CONFIG_STM32_SPI4 */ /* Create a RAM MTD device if configured */ #if defined(CONFIG_RAMMTD) && defined(CONFIG_STM32F429I_DISCO_RAMMTD) { uint8_t *start = (uint8_t *) kmm_malloc(CONFIG_STM32F429I_DISCO_RAMMTD_SIZE * 1024); mtd = rammtd_initialize(start, CONFIG_STM32F429I_DISCO_RAMMTD_SIZE * 1024); mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); /* Now initialize a SMART Flash block device and bind it to the MTD device */ #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) smart_initialize(CONFIG_STM32F429I_DISCO_RAMMTD_MINOR, mtd, NULL); #endif } #endif /* CONFIG_RAMMTD && CONFIG_STM32F429I_DISCO_RAMMTD */ #ifdef HAVE_USBHOST /* Initialize USB host operation. stm32_usbhost_initialize() starts a thread * will monitor for USB connection and disconnection events. */ ret = stm32_usbhost_initialize(); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to initialize USB host: %d\n", ret); return ret; } #endif #ifdef HAVE_USBMONITOR /* Start the USB Monitor */ ret = usbmonitor_start(); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to start USB monitor: %d\n", ret); } #endif #if defined(CONFIG_I2C) && defined(CONFIG_MPU6050) stm32_mpu6050_initialize("/dev/mpu6050"); #endif return OK; }
/* * * @param file Pointer to the file * @param debug Turn on debug printing * * @ingroup inputfiles */ void ct2ctml(const char* file, const int debug) { #ifdef HAS_NO_PYTHON /* * Section to bomb out if python is not * present in the computation environment. */ string ppath = file; throw CanteraError("ct2ctml", "python cti to ctml conversion requested for file, " + ppath + ", but not available in this computational environment"); #endif time_t aclock; time( &aclock ); int ia = static_cast<int>(aclock); string path = tmpDir()+"/.cttmp"+int2str(ia)+".pyw"; ofstream f(path.c_str()); if (!f) { throw CanteraError("ct2ctml","cannot open "+path+" for writing."); } f << "from ctml_writer import *\n" << "import sys, os, os.path\n" << "file = \"" << file << "\"\n" << "base = os.path.basename(file)\n" << "root, ext = os.path.splitext(base)\n" << "dataset(root)\n" << "execfile(file)\n" << "write()\n"; f.close(); string logfile = tmpDir()+"/ct2ctml.log"; #ifdef WIN32 string cmd = pypath() + " " + "\"" + path + "\"" + "> " + logfile + " 2>&1"; #else string cmd = "sleep " + sleep() + "; " + "\"" + pypath() + "\"" + " " + "\"" + path + "\"" + " &> " + logfile; #endif #ifdef DEBUG_PATHS writelog("ct2ctml: executing the command " + cmd + "\n"); #endif if (debug > 0) { writelog("ct2ctml: executing the command " + cmd + "\n"); writelog("ct2ctml: the Python command is: " + pypath() + "\n"); } int ierr = 0; try { ierr = system(cmd.c_str()); } catch (...) { ierr = -10; if (debug > 0) { writelog("ct2ctml: command execution failed.\n"); } } /* * This next section may seem a bit weird. However, it is in * response to an issue that arises when running cantera with * cygwin, using cygwin's python intepreter. Basically, the * xml file is written to the local directory by the last * system command. Then, the xml file is read immediately * after by an ifstream() c++ command. Unfortunately, it seems * that the directory info is not being synched fast enough so * that the ifstream() read fails, even though the file is * actually there. Putting in a sleep system call here fixes * this problem. Also, having the xml file pre-existing fixes * the problem as well. There may be more direct ways to fix * this bug; however, I am not aware of them. * HKM -> During the solaris port, I found the same thing. * It probably has to do with NFS syncing problems. * 3/3/06 */ #ifndef WIN32 string sss = sleep(); if (debug > 0) { writelog("sleeping for " + sss + " secs+\n"); } cmd = "sleep " + sss; try { ierr = system(cmd.c_str()); } catch (...) { ierr = -10; writelog("ct2ctml: command execution failed.\n"); } #else // This command works on windows machines if Windows.h and Winbase.h are included // Sleep(5000); #endif // show the contents of the log file on the screen try { char ch=0; string s = ""; ifstream ferr("ct2ctml.log"); if (ferr) { while (!ferr.eof()) { ferr.get(ch); s += ch; if (ch == '\n') { writelog(s); s = ""; } } ferr.close(); } else { if (debug > 0) { writelog("cannot open ct2ctml.log for reading.\n"); } } } catch (...) { writelog("ct2ctml: caught something \n");; } if (ierr != 0) { string msg = cmd; writelog("ct2ctml: throw cantera error \n");; throw CanteraError("ct2ctml", "could not convert input file to CTML.\n " "Command line was: \n" + msg); } // if the conversion succeeded and DEBUG_PATHS is not defined, // then clean up by deleting the temporary Python file. #ifndef DEBUG_PATHS //#ifdef WIN32 //cmd = "cmd /C rm " + path; if (debug == 0) remove(path.c_str()); else { writelog("ct2ctml: retaining temporary file "+path+"\n"); } #else if (debug > 0) { writelog("ct2ctml: retaining temporary file "+path+"\n"); } #endif }
void ls(DIR *d){ struct stat fs; struct dirent *ent; while(ent=readdir(d)){ if(stat(ent->d_name,&fs))ferr(progname); if(!shh & !strncmp(ent->d_name, ".",1))continue; if(!shdd & (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")))continue; if(shr){ if(fs.st_mode & S_IFDIR)putchar('d'); else putchar('-'); if(fs.st_mode & S_IRUSR)putchar('r'); else putchar('-'); if(fs.st_mode & S_IWUSR)putchar('w'); else putchar('-'); if(fs.st_mode & S_IXUSR){ if(fs.st_mode & S_ISUID)putchar('s'); else putchar('x'); } else { if(fs.st_mode & S_ISUID)putchar('S'); else putchar('-'); } if(fs.st_mode & S_IRGRP)putchar('r'); else putchar('-'); if(fs.st_mode & S_IWGRP)putchar('w'); else putchar('-'); if(fs.st_mode & S_IXGRP){ if(fs.st_mode & S_ISUID)putchar('s'); else putchar('x'); } else { if(fs.st_mode & S_ISUID)putchar('S'); else putchar('-'); } if(fs.st_mode & S_IROTH)putchar('r'); else putchar('-'); if(fs.st_mode & S_IWOTH)putchar('w'); else putchar('-'); if(fs.st_mode & S_IXOTH){ if((fs.st_mode & S_IFDIR) & (fs.st_mode & S_ISVTX))putchar('t'); else putchar('x'); } else { if((fs.st_mode & S_IFDIR) & (fs.st_mode & S_ISVTX))putchar('T'); else putchar('-'); } putchar(' '); } if(!nsu&shu){ struct passwd *pw; pw=getpwuid(fs.st_uid); printf("%s ",pw->pw_name); } if(!nsg&shg){ struct group *grp; grp=getgrgid(fs.st_gid); printf("%s ",grp->gr_name); } if(!nsu&sui)printf("%i ",fs.st_uid); if(!nsg&sgi)printf("%i ",fs.st_gid); if(shs)printf("%li ",fs.st_size); if(shi)printf("%li ",fs.st_ino); if(smt){ char *mt, mtn; if(shc)mt=ctime(&fs.st_ctime); else if(sat) mt=ctime(&fs.st_atime); else mt=ctime(&fs.st_mtime); strncat(&mtn, mt, strlen(mt)-1); printf("%s ",&mtn); } printf("%s", ent->d_name); if((sht || shd) & S_ISDIR(fs.st_mode))putchar('/'); if(sht){ if(S_ISLNK(fs.st_mode))putchar('@'); if(S_ISFIFO(fs.st_mode))putchar('|'); if(S_IXUSR & fs.st_mode)putchar('*'); if(S_IFSOCK & fs.st_mode)putchar('='); } struct dirent *chk; if(chk=readdir(d)){ if(wre)putchar('\n'); else if(wrc)printf(", "); else putchar('\t'); } } }
int ftl_initialize(int minor, FAR struct mtd_dev_s *mtd) { struct ftl_struct_s *dev; char devname[16]; int ret = -ENOMEM; /* Sanity check */ #ifdef CONFIG_DEBUG_FEATURES if (minor < 0 || minor > 255 || !mtd) { return -EINVAL; } #endif /* Allocate a FTL device structure */ dev = (struct ftl_struct_s *)kmm_malloc(sizeof(struct ftl_struct_s)); if (dev) { /* Initialize the FTL device structure */ dev->mtd = mtd; /* Get the device geometry. (casting to uintptr_t first eliminates * complaints on some architectures where the sizeof long is different * from the size of a pointer). */ ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->geo)); if (ret < 0) { ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret); kmm_free(dev); return ret; } /* Allocate one, in-memory erase block buffer */ #ifdef CONFIG_FS_WRITABLE dev->eblock = (FAR uint8_t *)kmm_malloc(dev->geo.erasesize); if (!dev->eblock) { ferr("ERROR: Failed to allocate an erase block buffer\n"); kmm_free(dev); return -ENOMEM; } #endif /* Get the number of R/W blocks per erase block */ dev->blkper = dev->geo.erasesize / dev->geo.blocksize; DEBUGASSERT(dev->blkper * dev->geo.blocksize == dev->geo.erasesize); /* Configure read-ahead/write buffering */ #ifdef FTL_HAVE_RWBUFFER dev->rwb.blocksize = dev->geo.blocksize; dev->rwb.nblocks = dev->geo.neraseblocks * dev->blkper; dev->rwb.dev = (FAR void *)dev; #if defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FTL_WRITEBUFFER) dev->rwb.wrmaxblocks = dev->blkper; dev->rwb.wrflush = ftl_flush; #endif #ifdef CONFIG_FTL_READAHEAD dev->rwb.rhmaxblocks = dev->blkper; dev->rwb.rhreload = ftl_reload; #endif ret = rwb_initialize(&dev->rwb); if (ret < 0) { ferr("ERROR: rwb_initialize failed: %d\n", ret); kmm_free(dev); return ret; } #endif /* Create a MTD block device name */ snprintf(devname, 16, "/dev/mtdblock%d", minor); /* Inode private data is a reference to the FTL device structure */ ret = register_blockdriver(devname, &g_bops, 0, dev); if (ret < 0) { ferr("ERROR: register_blockdriver failed: %d\n", -ret); kmm_free(dev); } } return ret; }
/* readelfheader() reads the ELF header into our global variable, and * checks to make sure that this is in fact a file that we should be * munging. */ static int readelfheader(int fd, Elf_Ehdr *ehdr) { errno = 0; if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) { return ferr("missing or incomplete ELF header."); } /* Check the ELF signature. */ if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 && ehdr->e_ident[EI_MAG1] == ELFMAG1 && ehdr->e_ident[EI_MAG2] == ELFMAG2 && ehdr->e_ident[EI_MAG3] == ELFMAG3)) { printf("missing ELF signature."); exit(0); } /* Compare the file's class and endianness with the program's. */ if (ELF_DATA == ELFDATA2LSB) { /* 2's complement, little endian */ if (!little_endian) { fprintf(stderr,"Warning! Host and target endianess don't match!\n"); swap_bytes=1; } } else if (ELF_DATA == ELFDATA2MSB) { /* 2's complement, big endian */ if (little_endian) { fprintf(stderr,"Warning! Host and target endianess don't match!\n"); swap_bytes=1; } } else { err("Unknown endianess type."); } if (ELF_CLASS == ELFCLASS64) { if (sizeof(void *)!=8) err("host!=elf word size not supported"); } else if (ELF_CLASS == ELFCLASS32) { if (sizeof(void *)!=4) err("host!=elf word size not supported"); } else { err("Unknown word size"); } if (ehdr->e_ident[EI_DATA] != ELF_DATA) { err("ELF file has different endianness."); } if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) { err("ELF file has different word size."); } /* Check the target architecture. */ { unsigned short machine; machine=ehdr->e_machine; if (swap_bytes) machine=bswap_16(machine); if (machine != ELF_ARCH) { fprintf(stderr, "Warning! " "ELF file created for different architecture: %d\n", ehdr->e_machine); } } /* Verify the sizes of the ELF header and the program segment * header table entries. */ { short ehsize; ehsize=ehdr->e_ehsize; if (swap_bytes) ehsize=bswap_16(ehsize); if (ehsize != sizeof(Elf_Ehdr)) { fprintf(stderr,"Warning! " "unrecognized ELF header size: %d != %ld\n", ehdr->e_ehsize,(long)sizeof(Elf_Ehdr)); } } { short phentsize; phentsize=ehdr->e_phentsize; if (swap_bytes) phentsize=bswap_16(phentsize); if (phentsize != sizeof(Elf_Phdr)) { fprintf(stderr,"Warning! " "unrecognized program segment header size: %d != %ld\n", ehdr->e_phentsize,(long)sizeof(Elf_Phdr)); } } /* Finally, check the file type. */ {short e_type; e_type=ehdr->e_type; if (swap_bytes) e_type=bswap_16(e_type); if (e_type != ET_EXEC && e_type != ET_DYN) { return err("not an executable or shared-object library."); } } return 1; }
/* main() loops over the cmdline arguments, leaving all the real work * to the other functions. */ int main(int argc, char *argv[]) { int fd; union { Elf32_Ehdr ehdr32; Elf64_Ehdr ehdr64; } e; union { Elf32_Phdr *phdrs32; Elf64_Phdr *phdrs64; } p; unsigned long newsize; char **arg; int failures = 0; if (argc < 2 || argv[1][0] == '-') { printf("Usage: sstrip FILE...\n" "sstrip discards all nonessential bytes from an executable.\n\n" "Version 2.0-X Copyright (C) 2000,2001 Brian Raiter.\n" "Cross-devel hacks Copyright (C) 2004 Manuel Novoa III.\n" "This program is free software, licensed under the GNU\n" "General Public License. There is absolutely no warranty.\n"); return EXIT_SUCCESS; } progname = argv[0]; for (arg = argv + 1 ; *arg != NULL ; ++arg) { filename = *arg; fd = open(*arg, O_RDWR); if (fd < 0) { ferr("can't open"); ++failures; continue; } switch (readelfheaderident(fd, &e.ehdr32)) { case ELFCLASS32: if (!(readelfheader32(fd, &e.ehdr32) && readphdrtable32(fd, &e.ehdr32, &p.phdrs32) && getmemorysize32(&e.ehdr32, p.phdrs32, &newsize) && truncatezeros(fd, &newsize) && modifyheaders32(&e.ehdr32, p.phdrs32, newsize) && commitchanges32(fd, &e.ehdr32, p.phdrs32, newsize))) ++failures; break; case ELFCLASS64: if (!(readelfheader64(fd, &e.ehdr64) && readphdrtable64(fd, &e.ehdr64, &p.phdrs64) && getmemorysize64(&e.ehdr64, p.phdrs64, &newsize) && truncatezeros(fd, &newsize) && modifyheaders64(&e.ehdr64, p.phdrs64, newsize) && commitchanges64(fd, &e.ehdr64, p.phdrs64, newsize))) ++failures; break; default: ++failures; break; } close(fd); } return failures ? EXIT_FAILURE : EXIT_SUCCESS; }
static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer, size_t buflen) { FAR struct part_procfs_file_s *attr; FAR struct mtd_geometry_s geo; ssize_t total = 0; ssize_t blkpererase; ssize_t ret; #ifdef CONFIG_MTD_PARTITION_NAMES char partname[11]; FAR const char *ptr; uint8_t x; #endif finfo("buffer=%p buflen=%d\n", buffer, (int)buflen); /* Recover our private data from the struct file instance */ attr = (FAR struct part_procfs_file_s *)filep->f_priv; DEBUGASSERT(attr); /* If we are at the end of the list, then return 0 signifying the * end-of-file. This also handles the special case when there are * no registered MTD partitions. */ if (attr->nextpart) { /* Output a header before the first entry */ if (attr->nextpart == g_pfirstpartition) { #ifdef CONFIG_MTD_PARTITION_NAMES total = snprintf(buffer, buflen, "Name Start Size"); #else total = snprintf(buffer, buflen, " Start Size"); #endif #ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD total += snprintf(&buffer[total], buflen - total, " MTD\n"); #else total += snprintf(&buffer[total], buflen - total, "\n"); #endif } /* Provide the requested data */ do { /* Get the geometry of the FLASH device */ ret = attr->nextpart->parent->ioctl(attr->nextpart->parent, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo)); if (ret < 0) { ferr("ERROR: mtd->ioctl failed: %d\n", ret); return 0; } /* Get the number of blocks per erase. There must be an even number * of blocks in one erase blocks. */ blkpererase = geo.erasesize / geo.blocksize; /* Copy data from the next known partition */ #ifdef CONFIG_MTD_PARTITION_NAMES if (attr->nextpart->name == NULL) { strcpy(partname, "(noname) "); } else { ptr = attr->nextpart->name; for (x = 0; x < sizeof(partname) - 1; x++) { /* Test for end of partition name */ if (*ptr == ',' || *ptr == '\0') { /* Perform space fill for alignment */ partname[x] = ' '; } else { /* Copy next byte of partition name */ partname[x] = *ptr++; } } partname[x] = '\0'; } /* Terminate the partition name and add to output buffer */ ret = snprintf(&buffer[total], buflen - total, "%s%7d %7d", partname, attr->nextpart->firstblock / blkpererase, attr->nextpart->neraseblocks); #else ret = snprintf(&buffer[total], buflen - total, "%7d %7d", attr->nextpart->firstblock / blkpererase, attr->nextpart->neraseblocks); #endif #ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD if (ret + total < buflen) { ret += snprintf(&buffer[total + ret], buflen - (total + ret), " %s\n", attr->nextpart->parent->name); } #else if (ret + total < buflen) { ret += snprintf(&buffer[total + ret], buflen - (total + ret), "\n"); } #endif if (ret + total < buflen) { /* It fit in the buffer totally. Advance total and move to * next partition. */ total += ret; attr->nextpart = attr->nextpart->pnext; } else { /* This one didn't fit completely. Truncate the partial * entry and break the loop. */ buffer[total] = '\0'; break; } } while (attr->nextpart); } /* Update the file offset */ if (total > 0) { filep->f_pos += total; } return total; }
void WRblock(block *b) { if (OPTIMIZER) { if (b && b->Bweight) dbg_printf("B%d: (%p), weight=%d",b->Bdfoidx,b,b->Bweight); else dbg_printf("block %p",b); if (!b) { ferr("\n"); return; } dbg_printf(" flags=x%x weight=%d",b->Bflags,b->Bweight); #if 0 dbg_printf("\tfile %p, line %d",b->Bfilptr,b->Blinnum); #endif dbg_printf(" "); WRBC(b->BC); dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex); #if SCPP if (b->BC == BCtry) dbg_printf(" catchvar = %p",b->catchvar); #endif dbg_printf("\n"); dbg_printf("\tBpred: "); WRblocklist(b->Bpred); dbg_printf("\tBsucc: "); WRblocklist(b->Bsucc); if (b->Belem) { if (debugf) /* if full output */ elem_print(b->Belem); else { ferr("\t"); WReqn(b->Belem); dbg_printf(";\n"); } } if (b->Bcode) b->Bcode->print(); ferr("\n"); } else { targ_llong *pu; int ncases; list_t bl; assert(b); dbg_printf("********* Basic Block %p ************\n",b); if (b->Belem) elem_print(b->Belem); dbg_printf("block: "); WRBC(b->BC); dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex); dbg_printf("\n"); dbg_printf("\tBpred:\n"); for (bl = b->Bpred; bl; bl = list_next(bl)) dbg_printf("\t%p\n",list_block(bl)); bl = b->Bsucc; switch (b->BC) { case BCswitch: pu = b->BS.Bswitch; assert(pu); ncases = *pu; dbg_printf("\tncases = %d\n",ncases); dbg_printf("\tdefault: %p\n",list_block(bl)); while (ncases--) { bl = list_next(bl); dbg_printf("\tcase %lld: %p\n",*++pu,list_block(bl)); } break; case BCiftrue: case BCgoto: case BCasm: #if SCPP case BCtry: case BCcatch: #endif case BCjcatch: case BC_try: case BC_filter: case BC_finally: case BC_ret: case BC_except: Lsucc: dbg_printf("\tBsucc:\n"); for ( ; bl; bl = list_next(bl)) dbg_printf("\t%p\n",list_block(bl)); break; case BCret: case BCretexp: case BCexit: break; default: assert(0); } } }
FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, off_t firstblock, off_t nblocks) { FAR struct mtd_partition_s *part; FAR struct mtd_geometry_s geo; unsigned int blkpererase; off_t erasestart; off_t eraseend; off_t devblocks; int ret; DEBUGASSERT(mtd); /* Get the geometry of the FLASH device */ ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo)); if (ret < 0) { ferr("ERROR: mtd->ioctl failed: %d\n", ret); return NULL; } /* Get the number of blocks per erase. There must be an even number of * blocks in one erase blocks. */ blkpererase = geo.erasesize / geo.blocksize; DEBUGASSERT(blkpererase * geo.blocksize == geo.erasesize); /* Adjust the offset and size if necessary so that they are multiples of * the erase block size (making sure that we do not go outside of the * requested sub-region). NOTE that 'eraseend' is the first erase block * beyond the sub-region. */ erasestart = (firstblock + blkpererase - 1) / blkpererase; eraseend = (firstblock + nblocks) / blkpererase; if (erasestart >= eraseend) { ferr("ERROR: sub-region too small\n"); return NULL; } /* Verify that the sub-region is valid for this geometry */ devblocks = blkpererase * geo.neraseblocks; if (eraseend > devblocks) { ferr("ERROR: sub-region too big\n"); return NULL; } /* Allocate a partition device structure */ part = (FAR struct mtd_partition_s *)kmm_zalloc(sizeof(struct mtd_partition_s)); if (!part) { ferr("ERROR: Failed to allocate memory for the partition device\n"); return NULL; } /* Initialize the partition device structure. (unsupported methods were * nullified by kmm_zalloc). */ part->child.erase = part_erase; part->child.bread = part_bread; part->child.bwrite = part_bwrite; part->child.read = mtd->read ? part_read : NULL; part->child.ioctl = part_ioctl; #ifdef CONFIG_MTD_BYTE_WRITE part->child.write = mtd->write ? part_write : NULL; #endif part->parent = mtd; part->firstblock = erasestart * blkpererase; part->neraseblocks = eraseend - erasestart; part->blocksize = geo.blocksize; part->blkpererase = blkpererase; #ifdef CONFIG_MTD_PARTITION_NAMES part->name = NULL; #endif #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_PROCFS_EXCLUDE_PARTITIONS) /* Add this partition to the list of known partitions */ if (g_pfirstpartition == NULL) { g_pfirstpartition = part; } else { struct mtd_partition_s *plast; /* Add the partition to the end of the list */ part->pnext = NULL; plast = g_pfirstpartition; while (plast->pnext != NULL) { /* Get pointer to next partition */ plast = plast->pnext; } plast->pnext = part; } #endif /* Return the implementation-specific state structure as the MTD device */ return &part->child; }
int block_proxy(FAR const char *blkdev, int oflags) { FAR char *chardev; bool readonly; int ret; int fd; DEBUGASSERT(blkdev); /* Create a unique temporary file name for the character device */ chardev = unique_chardev(); if (chardev == NULL) { ferr("ERROR: Failed to create temporary device name\n"); return -ENOMEM; } /* Should this character driver be read-only? */ readonly = ((oflags & O_WROK) == 0); /* Wrap the block driver with an instance of the BCH driver */ ret = bchdev_register(blkdev, chardev, readonly); if (ret < 0) { ferr("ERROR: bchdev_register(%s, %s) failed: %d\n", blkdev, chardev, ret); goto errout_with_chardev; } /* Open the newly created character driver */ oflags &= ~(O_CREAT | O_EXCL | O_APPEND | O_TRUNC); fd = open(chardev, oflags); if (fd < 0) { ret = -errno; ferr("ERROR: Failed to open %s: %d\n", chardev, ret); goto errout_with_bchdev; } /* Unlink the character device name. The driver instance will persist, * provided that CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y (otherwise, we have * a problem here!) */ ret = unlink(chardev); if (ret < 0) { ret = -errno; ferr("ERROR: Failed to unlink %s: %d\n", chardev, ret); } /* Free the allocate character driver name and return the open file * descriptor. */ kmm_free(chardev); return fd; errout_with_bchdev: (void)unlink(chardev); errout_with_chardev: kmm_free(chardev); return ret; }
static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir) { FAR struct proc_dir_s *procdir; FAR const struct proc_node_s *node; FAR struct tcb_s *tcb; irqstate_t flags; unsigned long tmp; FAR char *ptr; pid_t pid; finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL"); DEBUGASSERT(relpath != NULL && dir != NULL && dir->u.procfs == NULL); /* The relative must be either: * * (1) "<pid>" - The sub-directory of task/thread attributes, * (2) "self" - Which refers to the PID of the calling task, or * (3) The name of a directory node under either of those */ /* Otherwise, the relative path should be a valid task/thread ID */ ptr = NULL; if (strncmp(relpath, "self", 4) == 0) { tmp = (unsigned long)getpid(); /* Get the PID of the calling task */ ptr = (FAR char *)relpath + 4; /* Discard const */ } else { tmp = strtoul(relpath, &ptr, 10); /* Extract the PID from path */ } if (ptr == NULL || (*ptr != '\0' && *ptr != '/')) { /* strtoul failed or there is something in the path after the pid */ ferr("ERROR: Invalid path \"%s\"\n", relpath); return -ENOENT; } /* A valid PID would be in the range of 0-32767 (0 is reserved for the * IDLE thread). */ if (tmp >= 32768) { ferr("ERROR: Invalid PID %ld\n", tmp); return -ENOENT; } /* Now verify that a task with this task/thread ID exists */ pid = (pid_t)tmp; flags = enter_critical_section(); tcb = sched_gettcb(pid); leave_critical_section(flags); if (tcb == NULL) { ferr("ERROR: PID %d is not valid\n", (int)pid); return -ENOENT; } /* Allocate the directory structure. Note that the index and procentry * pointer are implicitly nullified by kmm_zalloc(). Only the remaining, * non-zero entries will need be initialized. */ procdir = (FAR struct proc_dir_s *)kmm_zalloc(sizeof(struct proc_dir_s)); if (procdir == NULL) { ferr("ERROR: Failed to allocate the directory structure\n"); return -ENOMEM; } /* Was the <pid> the final element of the path? */ if (*ptr != '\0' && strcmp(ptr, "/") != 0) { /* There is something in the path after the pid. Skip over the path * segment delimiter and see if we can identify the node of interest. */ ptr++; node = proc_findnode(ptr); if (node == NULL) { ferr("ERROR: Invalid path \"%s\"\n", relpath); kmm_free(procdir); return -ENOENT; } /* The node must be a directory, not a file */ if (!DIRENT_ISDIRECTORY(node->dtype)) { ferr("ERROR: Path \"%s\" is not a directory\n", relpath); kmm_free(procdir); return -ENOTDIR; } /* This is a second level directory */ procdir->base.level = 2; procdir->base.nentries = PROC_NGROUPNODES; procdir->node = node; } else { /* Use the special level0 node */ procdir->base.level = 1; procdir->base.nentries = PROC_NLEVEL0NODES; procdir->node = &g_level0node; } procdir->pid = pid; dir->u.procfs = (FAR void *)procdir; return OK; }