Example #1
0
/*---------------------------------------------------------------------------*/
static void *
find_local_symbol(int fd, const char *symbol,
		  unsigned int symtab, unsigned short symtabsize,
		  unsigned int strtab)
{
  struct elf32_sym s;
  unsigned int a;
  char name[30];
  struct relevant_section *sect;
  
  for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) {
    seek_read(fd, a, (char *)&s, sizeof(s));

    if(s.st_name != 0) {
      seek_read(fd, strtab + s.st_name, name, sizeof(name));
      if(strcmp(name, symbol) == 0) {
	if(s.st_shndx == bss.number) {
	  sect = &bss;
	} else if(s.st_shndx == data.number) {
	  sect = &data;
  } else if(s.st_shndx == rodata.number) {
    sect = &rodata;
	} else if(s.st_shndx == text.number) {
	  sect = &text;
	} else {
	  return NULL;
	}
	return &(sect->address[s.st_value]);
      }
    }
  }
  return NULL;
}
Example #2
0
File: fs.c Project: rbkloss/dcc_fs
uint64_t fs_get_block(struct superblock *sb) {
    if (sb->freeblks == 0) {
        //report Error
        return 0;
    }
    uint64_t freeList = sb->freelist;
    struct freepage *fp = (struct freepage *) malloc(sb->blksz);
    struct freepage *fp_prev = (struct freepage *) malloc(sb->blksz);
    struct freepage *fp_next = (struct freepage *) malloc(sb->blksz);
    seek_read(sb, freeList, fp);
    if (fp->count != 0) {
        //update previous pointers        
        seek_read(sb, fp->links[0], fp_prev);
        fp_prev->next = fp->next;
        seek_write(sb, fp->links[0], fp_prev);
    }

    if (fp->next != 0) {
        //update next pointers        
        seek_read(sb, fp->next, fp_next);
        fp_next->links[0] = fp->links[0];
        seek_write(sb, fp->next, fp_next);
    }

    sb->freelist = fp->next;
    sb->freeblks--;
    seek_write(sb, 0, sb);

    free(fp_prev);
    free(fp);
    free(fp_next);
    return freeList;
}
Example #3
0
/*---------------------------------------------------------------------------*/
static void *
find_program_processes(int fd,
                       unsigned int symtab, unsigned short size,
                       unsigned int strtab)
{
    struct elf32_sym s;
    unsigned int a;
    char name[30];

    for(a = symtab; a < symtab + size; a += sizeof(s))
    {
        seek_read(fd, a, (char *)&s, sizeof(s));

        if(s.st_name != 0)
        {
            seek_read(fd, strtab + s.st_name, name, sizeof(name));
            if(strcmp(name, "autostart_processes") == 0)
            {
                return &data.address[s.st_value];
            }
        }
    }
    return NULL;
    /*   return find_local_symbol(fd, "autostart_processes", symtab, size, strtab); */
}
Example #4
0
uint64_t findFile(const struct superblock* sb, const char* fname, int* exists) {
    assert(exists != NULL);
    struct inode* node, *ent;

    if (strcmp("/", fname) == 0) {
        *exists = TRUE;
        return sb->root;
    }

    initNode(&node, sb->blksz);
    initNode(&ent, sb->blksz);
    struct nodeinfo *meta = (struct nodeinfo*) malloc(sb->blksz);
    int len = 0;
    char** fileParts = getFileParts(fname, &len);

    *exists = FALSE;
    uint64_t fileBlock = sb->root;
    seek_read(sb, fileBlock, node);
    int it = 1;
    while (it < len) {
        int foundEnt = FALSE;
        int i = 0;
        do {
            while (node->links[i] != 0) {
                seek_read(sb, node->links[i], ent);
                seek_read(sb, ent->meta, meta);
                if (strcmp(meta->name, fileParts[it]) == 0) {
                    foundEnt = TRUE;
                    fileBlock = node->links[i];
                    it++;
                    break;
                }
                i++;
            }
            if ((foundEnt || node->next == 0))break;
            seek_read(sb, node->next, node);
        } while (node->next != 0);
        if (foundEnt) {
            seek_read(sb, fileBlock, node);
        } else {
            *exists = FALSE;
            free(node);
            free(ent);
            free(meta);
            freeFileParts(&fileParts, len);
            return fileBlock;
        }
    }

    if (it >= len) *exists = TRUE;
    freeFileParts(&fileParts, len);
    free(node);
    free(ent);
    free(meta);
    return fileBlock;
}
Example #5
0
uint64_t getNodeLastLinkBlock(const struct superblock* sb, uint64_t nodeBlock) {
    uint64_t ans = nodeBlock;
    struct inode* node = NULL;
    node = malloc(sb->blksz);
    seek_read(sb, nodeBlock, node);
    while (node->next != 0) {
        ans = node->next;
        seek_read(sb, node->next, node);
    }
    free(node);
    return ans;
}
Example #6
0
bool SND_In_File::read(vec &v)
{
  if (!good())
    return false;

  int i, n;

  n = samples();
  v.set_size(n, false);
  seek_read(0);

  bool switch_endian = !is_bigendian(); // if LITTLE_ENDIAN than switch
  switch (header.encoding) {
  case enc_linear8 :
    for (i = 0; i < n; i++)
      v(i) = read_endian<char>(file, switch_endian) / 128.0;
    break;
  case enc_linear16 :
    for (i = 0; i < n; i++)
      v(i) = read_endian<short>(file, switch_endian) / 32768.0;
    break;
  case enc_float :
    for (i = 0; i < n; i++)
      v(i) = read_endian<float>(file, switch_endian);
    break;
  case enc_double :
    for (i = 0; i < n; i++)
      v(i) = read_endian<double>(file, switch_endian);
    break;
  default :
    it_warning("SND_In_File::read(): Unsupported encoding!");
    return false;
  }
  return file.good();
}
Example #7
0
File: fs.c Project: rbkloss/dcc_fs
int fs_put_block(struct superblock *sb, uint64_t block) {
    if (sb->freeblks != 0) {
        uint64_t freeList = sb->freelist;
        struct freepage *fp = NULL, *fp_next = NULL;
        fp = (struct freepage *) malloc(sb->blksz);
        fp_next = (struct freepage *) malloc(sb->blksz);

        seek_read(sb, freeList, fp_next);
        fp->next = freeList;
        fp->count = 0;
        seek_write(sb, block, fp);
        fp_next->count = 1;
        fp_next->links[0] = block;
        seek_write(sb, freeList, fp_next);

        free(fp);
        free(fp_next);
    } else {
        struct freepage *fp = NULL;
        fp = (struct freepage *) malloc(sb->blksz);
        fp->next = 0;
        fp->count = 0;
        seek_write(sb, block, fp);
        free(fp);
    }
    sb->freelist = block;
    sb->freeblks++;
    seek_write(sb, 0, sb);
    return 0;
}
Example #8
0
int InsertInNode(struct superblock* sb, const char* dirName,
        const uint64_t fileBlock) {
    int exists;
    struct inode*dirNode = NULL;
    struct nodeinfo* meta = NULL;
    dirNode = malloc(sb->blksz);
    meta = malloc(sb->blksz);
    uint64_t dirBlock = findFile(sb, dirName, &exists);
    seek_read(sb, dirBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    int len = 0;
    char** fileparts = getFileParts(dirName, &len);
    if (strcmp(meta->name, fileparts[len - 1]) != 0)return 0; //dir does not exists
    if ((++meta->size) % getLinksMaxLen(sb) == 0) {
        //needs to create another link block      
        struct inode* linknode = NULL;
        linknode = malloc(sb->blksz);
        linknode->links[0] = fileBlock;
        linknode->links[1] = 0;
        uint64_t lastLinkBlock = getNodeLastLinkBlock(sb, dirBlock);
        struct inode* lastLinkNode = NULL;
        lastLinkNode = malloc(sb->blksz);
        seek_read(sb, lastLinkBlock, lastLinkNode);
        if (lastLinkNode->next != 0) {
            exit(EXIT_FAILURE);
        }
        lastLinkNode->next = fs_get_block(sb);
        seek_write(sb, lastLinkNode->next, linknode);
        seek_write(sb, lastLinkBlock, lastLinkNode);
        free(linknode);
        free(lastLinkNode);
    } else {
        int linkLen = getLinksLen(dirNode);
        dirNode->links[linkLen] = fileBlock;
        dirNode->links[linkLen + 1] = 0;
    }
    seek_write(sb, dirBlock, dirNode);
    seek_write(sb, dirNode->meta, meta);

    freeFileParts(&fileparts, len);
    free(dirNode);
    free(meta);
    return FALSE;
}
Example #9
0
File: fs.c Project: rbkloss/dcc_fs
ssize_t fs_read_file(struct superblock *sb, const char *fname, char *buf,
        size_t bufsz) {
    if (existsFile(sb, fname) == FALSE) {
        errno = ENOENT;
        return -1;
    }
    int len = 0, exists = 0;
    char** fileParts = getFileParts(fname, &len);

    uint64_t fileBlock = findFile(sb, fname, &exists);

    struct inode* node;
    initNode(&node, sb->blksz);
    struct nodeinfo* meta = (struct nodeinfo*) calloc(1, sb->blksz);

    seek_read(sb, fileBlock, node);
    seek_read(sb, node->meta, meta);
    assert(strcmp(meta->name, fileParts[len - 1]) == 0);

    size_t size = MIN(meta->size, bufsz);
    size = MAX(sb->blksz, size);
    size_t read_blocks = 0;

    char* buf_p = (char*) calloc(1, size);
    char* p = buf_p;
    do {
        int i = 0;
        while (node->links[i] != 0) {
            seek_read(sb, node->links[i++], p);
            p = p + sb->blksz;
            read_blocks++;
        }
        if (node->next == 0)break;
        seek_read(sb, node->next, node);
    } while (node->next != 0);
    strcpy(buf, buf_p);
    freeFileParts(&fileParts, len);
    free(meta);
    free(node);
    free(buf_p);
    return size;
}
Example #10
0
/**
 * Inserts block2Add in the links relative to destBlock.
 * Does not check if destBlock is valid!
 * @param sb the superblock
 * @param destBlock block to receive block2Add as a child
 * @param block2Add block to be added in the children of destBlock
 * @return as of now you can ignore this
 */
int insertInBlock(struct superblock* sb, const uint64_t destBlock,
        const uint64_t block2Add) {
    struct inode *dirNode = NULL;
    struct nodeinfo* meta = NULL;
    dirNode = malloc(sb->blksz);
    meta = malloc(sb->blksz);
    seek_read(sb, destBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    if ((++meta->size) % getLinksMaxLen(sb) == 0) {
        //needs to create another link block      
        struct inode* linknode = NULL;
        linknode = malloc(sb->blksz);
        linknode->links[0] = block2Add;
        linknode->links[1] = 0;
        uint64_t lastLinkBlock = getNodeLastLinkBlock(sb, destBlock);
        struct inode* lastLinkNode = NULL;
        lastLinkNode = malloc(sb->blksz);
        seek_read(sb, lastLinkBlock, lastLinkNode);
        if (lastLinkNode->next != 0) {
            exit(EXIT_FAILURE);
        }
        lastLinkNode->next = fs_get_block(sb);
        seek_write(sb, lastLinkNode->next, linknode);
        seek_write(sb, lastLinkBlock, lastLinkNode);
        free(linknode);
        free(lastLinkNode);
    } else {
        int linkLen = getLinksLen(dirNode);
        dirNode->links[linkLen] = block2Add;
        dirNode->links[linkLen + 1] = 0;
    }
    seek_write(sb, destBlock, dirNode);
    seek_write(sb, dirNode->meta, meta);

    free(dirNode);
    free(meta);
    return TRUE;
}
Example #11
0
File: fs.c Project: rbkloss/dcc_fs
int checkfather_path(struct superblock *sb, const char *dname, struct inode* father) {

    struct nodeinfo* info_pai = (struct nodeinfo*) malloc(sb->blksz);
    seek_read(sb, father->meta, info_pai);

    int size = 0;
    char **dname_array = getFileParts(dname, &size);

    int valid = 0;
    if (size >= 2)
        valid = strcmp(dname_array[size - 2], info_pai->name);

    freeFileParts(&dname_array, size);
    free(info_pai);
    info_pai = NULL;

    if (valid == 0) {
        return success;
    } else {
        return invalid;
    }
}
Example #12
0
//////////////////////////////////////////////////
//
// SND_IO_File
//
//////////////////////////////////////////////////
bool SND_IO_File::open(const char *fname)
{
  if (file.is_open())
    close();
  file.clear();
  is_valid = false;
  file.open(fname, ios::in | ios::out | ios::binary);
  if (!file)
    return false;

  if (!read_header(file)) {
    file.close();
    return false;
  }

  if (!seek_read(0) || !seek_write(0)) {
    file.close();
    return false;
  }

  is_valid = true;
  return true;
}
Example #13
0
File: fs.c Project: rbkloss/dcc_fs
int fs_mkdir(struct superblock *sb, const char *dname) {

    if (!sb->freeblks) {
        // disk is full
        errno = ENOSPC;
        return invalid;
    }

    int exists = 0;

    uint64_t fileBlock = findFile(sb, dname, &exists);

    if (exists) {
        // dir already exist;
        errno = EEXIST;
        return invalid;
    }

    struct inode *father = (struct inode*) malloc(sb->blksz);
    struct inode *folder = (struct inode*) malloc(sb->blksz);
    struct nodeinfo *n_info = (struct nodeinfo*) malloc(sb->blksz);

    uint64_t folder_block = fs_get_block(sb);
    uint64_t nodeinfo_block = fs_get_block(sb);

    init_folder_struct(folder, folder_block, nodeinfo_block);
    int status = init_nodeinfo_struct(sb, dname, n_info, nodeinfo_block);

    if (status == invalid) {
        free(father);
        father = NULL;

        free(folder);
        folder = NULL;

        free(n_info);
        n_info = NULL;

        errno = ENAMETOOLONG;
        return invalid;
    }

    /* Read father inode stored in file */
    seek_read(sb, fileBlock, father);
    status = checkfather_path(sb, dname, father);

    if (status == invalid) {
        free(father);
        father = NULL;

        free(folder);
        folder = NULL;

        free(n_info);
        n_info = NULL;

        errno = ENOENT;
        return invalid;
    }

    /* Ok, proceed */
    if (!exists) {
        insertInBlock(sb, fileBlock, folder_block);

        /* store both inodes related to the folder that
                 has been just created
         */
        seek_write(sb, folder_block, folder);
        seek_write(sb, nodeinfo_block, n_info);

    }


    free(father);
    father = NULL;
    free(folder);
    folder = NULL;
    free(n_info);
    n_info = NULL;

    return success;
}
Example #14
0
/*---------------------------------------------------------------------------*/
static int
relocate_section(int fd,
		 unsigned int section, unsigned short size,
		 unsigned int sectionaddr,
		 char *sectionbase,
		 unsigned int strs,
		 unsigned int strtab,
		 unsigned int symtab, unsigned short symtabsize,
		 unsigned char using_relas)
{
  /* sectionbase added; runtime start address of current section */
  struct elf32_rela rela; /* Now used both for rel and rela data! */
  int rel_size = 0;
  struct elf32_sym s;
  unsigned int a;
  char name[30];
  char *addr;
  struct relevant_section *sect;

  /* determine correct relocation entry sizes */
  if(using_relas) {
    rel_size = sizeof(struct elf32_rela);
  } else {
    rel_size = sizeof(struct elf32_rel);
  }
  
  for(a = section; a < section + size; a += rel_size) {
    seek_read(fd, a, (char *)&rela, rel_size);
    seek_read(fd,
	      symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info),
	      (char *)&s, sizeof(s));
    if(s.st_name != 0) {
      seek_read(fd, strtab + s.st_name, name, sizeof(name));
      PRINTF("name: %s\n", name);
      addr = (char *)symtab_lookup(name);
      /* ADDED */
      if(addr == NULL) {
	PRINTF("name not found in global: %s\n", name);
	addr = find_local_symbol(fd, name, symtab, symtabsize, strtab);
	PRINTF("found address %p\n", addr);
      }
      if(addr == NULL) {
	if(s.st_shndx == bss.number) {
	  sect = &bss;
	} else if(s.st_shndx == data.number) {
	  sect = &data;
	} else if(s.st_shndx == rodata.number) {
	  sect = &rodata;
	} else if(s.st_shndx == text.number) {
	  sect = &text;
	} else {
	  PRINTF("elfloader unknown name: '%30s'\n", name);
	  memcpy(elfloader_unknown, name, sizeof(elfloader_unknown));
	  elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
	  return ELFLOADER_SYMBOL_NOT_FOUND;
	}
	addr = sect->address;
      }
    } else {
      if(s.st_shndx == bss.number) {
	sect = &bss;
      } else if(s.st_shndx == data.number) {
	sect = &data;
      } else if(s.st_shndx == rodata.number) {
	sect = &rodata;
      } else if(s.st_shndx == text.number) {
	sect = &text;
      } else {
	return ELFLOADER_SEGMENT_NOT_FOUND;
      }
      
      addr = sect->address;
    }

    if(!using_relas) {
      /* copy addend to rela structure */
      seek_read(fd, sectionaddr + rela.r_offset, (char *)&rela.r_addend, 4);
    }

    elfloader_arch_relocate(fd, sectionaddr, sectionbase, &rela, addr);
  }
  return ELFLOADER_OK;
}
Example #15
0
File: fs.c Project: rbkloss/dcc_fs
char * fs_list_dir(struct superblock *sb, const char *dname) { //lista tudo o que tem dentro de dname.
    int i = 0, found, size, isDir;
    uint64_t dirBlock;
    int maxLink;
    char *names;

    struct inode *dir;
    struct inode *aux;
    struct nodeinfo *auxinfo;

    maxLink = getLinksMaxLen(sb);
    dir = (struct inode *) malloc(sb->blksz);
    aux = (struct inode *) malloc(sb->blksz);
    auxinfo = (struct nodeinfo *) malloc(sb->blksz);
    names = (char *) malloc(sizeof (char));

    strcpy(names, ""); //comecara 'nulo'

    dirBlock = findFile(sb, dname, &found); //vasculhandodo o diretorio

    if (found == 0) { //o dretorio nao existe
        errno = ENOENT;
        return NULL;
    }

    seek_read(sb, dirBlock, dir); //pegando inode do diretorio
    if (dir->mode != IMDIR) { //se nao for diretorio
        errno = ENOTDIR;
        return NULL;
    }

    while (i < maxLink && dir->links[i] != 0) { //buscar em todos os links do bloco

        seek_read(sb, dir->links[i], aux); //objeto de 'links', sempre sera inode IMREG ou IMDIR
        seek_read(sb, aux->meta, auxinfo); //nodeinfo dele

        if (aux->mode == IMDIR)
            isDir = 1;
        else
            isDir = 0;

        size = strlen(auxinfo->name) + 1 + isDir; //pegando tamanho do nome mais um espaco e mais uma barra (ou nao)
        char* temp = (char *) malloc((size + strlen(names) + 1) * sizeof (char));
        strcpy(temp, names);
        strcat(temp, auxinfo->name);
        free(names);
        names = temp;
        if (isDir)
            strcat(names, "/");
        strcat(names, " "); //concatenando espaco de separacao de nomes

        i++;
        if (i == maxLink && (dir->next != 0)) {
            i = 0; //tem next? reseta contagem
            seek_read(sb, dir->next, dir); //indo pro proximo inode, se houver.
        }
    }

    free(dir);
    free(aux);
    free(auxinfo);
    printf("%s\n", names);
    return names;
}
Example #16
0
File: fs.c Project: rbkloss/dcc_fs
int fs_delete_file(struct superblock *sb, const char *fname) { //o proprio nome ja diz.
    int i = 0, found, maxLink, ultimo;
    uint64_t fileBlock, fileLinkBlk, lastBlock, folderBlock; //numero do bloco e do bloco do link no diretorio que tem ele

    struct inode *file;
    struct inode *folder;
    struct inode *aux;
    struct nodeinfo *folderInfo;

    maxLink = getLinksMaxLen(sb);
    file = (struct inode *) malloc(sb->blksz);
    folder = (struct inode *) malloc(sb->blksz);
    aux = (struct inode *) malloc(sb->blksz);
    folderInfo = (struct nodeinfo *) malloc(sb->blksz);

    fileBlock = findFile(sb, fname, &found);

    if (found == 0) { //arquivo nao existe
        errno = ENOENT;
        return -1;
    }

    seek_read(sb, fileBlock, file); //pegando inode do arquivo
    if (file->mode == IMDIR) { //se for diretorio
        errno = EISDIR;
        return -1;
    }

    folderBlock = file->parent;
    fileLinkBlk = folderBlock;
    seek_read(sb, folderBlock, folder); //diretorio onde esta o arquivo
    seek_read(sb, folder->meta, folderInfo);


    //removendo o arquivo e blocos associados
    fs_put_block(sb, file->meta); //liberando bloco nodeinfo
    while ((i < maxLink) && (file->links[i] != 0)) {
        //if (i == maxLink)
        fs_put_block(sb, file->links[i]);
        file->links[i] = 0; //marcando que nao tem mais bloco neste link.
        i++;
        if (i == maxLink && file->next != 0) {
            seek_read(sb, file->next, file);
            fs_put_block(sb, file->meta); //apagando bloco anterior depois de ir pro próximo.
            i = 0;
        }
    }
    //removendo na pasta tambem;
    ultimo = (folder->links[getLinksLen(folder) - 1] == fileBlock);
    if (ultimo) {
        folder->links[getLinksLen(folder) - 1] = 0;
        //folderInfo->size--;
    } else {
        i = 0;
        while ((folder->links[i % maxLink] != fileBlock) && i < folderInfo->size) {
            i++;
            if ((i % maxLink == 0) && (folder->next != 0)) {
                fileLinkBlk = folder->next; //guardando bloco que pode conter link pro arquivo. Saindo do while sera ele.
                seek_read(sb, folder->next, folder);
            }
        }
        lastBlock = getNodeLastLinkBlock(sb, folderBlock);
        if (lastBlock == fileLinkBlk) {
            folder->links[i % maxLink] = folder->links[getLinksLen(folder) - 1];
            folder->links[getLinksLen(folder) - 1] = 0;
        } else {
            seek_read(sb, lastBlock, aux);
            folder->links[i % maxLink] = aux->links[getLinksLen(aux) - 1]; //copiando ultimo link pra posicao q indicava bloco do arquivo removido
            aux->links[getLinksLen(aux) - 1] = 0;
            seek_write(sb, lastBlock, aux); //Devo escrever o bloco alterado de volta no disco, certo?
        }

    }
    folderInfo->size--;

    seek_write(sb, fileLinkBlk, folder); //escrevendo o que contem o link pro arquivo (foi alterado ali em cima)
    seek_read(sb, folderBlock, folder); //voltando pro inode principal da pasta
    seek_write(sb, folder->meta, folderInfo); //pra escrever o folderinfo no bloco onde ele estava.

    free(file);
    free(folder);
    free(folderInfo);
    free(aux);

    return 0;
}
Example #17
0
/*---------------------------------------------------------------------------*/
int
elfloader_load(int fd)
{
  struct elf32_ehdr ehdr;
  struct elf32_shdr shdr;
  struct elf32_shdr strtable;
  unsigned int strs;
  unsigned int shdrptr;
  unsigned int nameptr;
  char name[12];
  
  int i;
  unsigned short shdrnum, shdrsize;

  unsigned char using_relas = -1;
  unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize;
  unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize;
  unsigned short rodataoff = 0, rodatasize, rodatarelaoff = 0, rodatarelasize;
  unsigned short symtaboff = 0, symtabsize;
  unsigned short strtaboff = 0, strtabsize;
  unsigned short bsssize = 0;

  struct process **process;
  int ret;

  elfloader_unknown[0] = 0;

  /* The ELF header is located at the start of the buffer. */
  seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr));

  /*  print_chars(ehdr.e_ident, sizeof(elf_magic_header));
      print_chars(elf_magic_header, sizeof(elf_magic_header));*/
  /* Make sure that we have a correct and compatible ELF header. */
  if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
    PRINTF("ELF header problems\n");
    return ELFLOADER_BAD_ELF_HEADER;
  }

  /* Grab the section header. */
  shdrptr = ehdr.e_shoff;
  seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr));
  
  /* Get the size and number of entries of the section header. */
  shdrsize = ehdr.e_shentsize;
  shdrnum = ehdr.e_shnum;

  PRINTF("Section header: size %d num %d\n", shdrsize, shdrnum);
  
  /* The string table section: holds the names of the sections. */
  seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
	    (char *)&strtable, sizeof(strtable));

  /* Get a pointer to the actual table of strings. This table holds
     the names of the sections, not the names of other symbols in the
     file (these are in the sybtam section). */
  strs = strtable.sh_offset;

  PRINTF("Strtable offset %d\n", strs);
  
  /* Go through all sections and pick out the relevant ones. The
     ".text" segment holds the actual code from the ELF file, the
     ".data" segment contains initialized data, the ".bss" segment
     holds the size of the unitialized data segment. The ".rel[a].text"
     and ".rel[a].data" segments contains relocation information for the
     contents of the ".text" and ".data" segments, respectively. The
     ".symtab" segment contains the symbol table for this file. The
     ".strtab" segment points to the actual string names used by the
     symbol table.

     In addition to grabbing pointers to the relevant sections, we
     also save the section number for resolving addresses in the
     relocator code.
  */


  /* Initialize the segment sizes to zero so that we can check if
     their sections was found in the file or not. */
  textsize = textrelasize = datasize = datarelasize =
    rodatasize = rodatarelasize = symtabsize = strtabsize = 0;

  bss.number = data.number = rodata.number = text.number = -1;
		
  shdrptr = ehdr.e_shoff;
  for(i = 0; i < shdrnum; ++i) {

    seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr));
    
    /* The name of the section is contained in the strings table. */
    nameptr = strs + shdr.sh_name;
    seek_read(fd, nameptr, name, sizeof(name));
    PRINTF("Section shdrptr 0x%x, %d + %d type %d\n",
	   shdrptr,
	   strs, shdr.sh_name,
	   (int)shdr.sh_type);
    /* Match the name of the section with a predefined set of names
       (.text, .data, .bss, .rela.text, .rela.data, .symtab, and
       .strtab). */
    /* added support for .rodata, .rel.text and .rel.data). */

    if(shdr.sh_type == SHT_SYMTAB/*strncmp(name, ".symtab", 7) == 0*/) {
      PRINTF("symtab\n");
      symtaboff = shdr.sh_offset;
      symtabsize = shdr.sh_size;
    } else if(shdr.sh_type == SHT_STRTAB/*strncmp(name, ".strtab", 7) == 0*/) {
      PRINTF("strtab\n");
      strtaboff = shdr.sh_offset;
      strtabsize = shdr.sh_size;
    } else if(strncmp(name, ".text", 5) == 0) {
      textoff = shdr.sh_offset;
      textsize = shdr.sh_size;
      text.number = i;
      text.offset = textoff;
    } else if(strncmp(name, ".rel.text", 9) == 0) {
      using_relas = 0;
      textrelaoff = shdr.sh_offset;
      textrelasize = shdr.sh_size;
    } else if(strncmp(name, ".rela.text", 10) == 0) {
      using_relas = 1;
      textrelaoff = shdr.sh_offset;
      textrelasize = shdr.sh_size;
    } else if(strncmp(name, ".data", 5) == 0) {
      dataoff = shdr.sh_offset;
      datasize = shdr.sh_size;
      data.number = i;
      data.offset = dataoff;
    } else if(strncmp(name, ".rodata", 7) == 0) {
      /* read-only data handled the same way as regular text section */
      rodataoff = shdr.sh_offset;
      rodatasize = shdr.sh_size;
      rodata.number = i;
      rodata.offset = rodataoff;
    } else if(strncmp(name, ".rel.rodata", 11) == 0) {
      /* using elf32_rel instead of rela */
      using_relas = 0;
      rodatarelaoff = shdr.sh_offset;
      rodatarelasize = shdr.sh_size;
    } else if(strncmp(name, ".rela.rodata", 12) == 0) {
      using_relas = 1;
      rodatarelaoff = shdr.sh_offset;
      rodatarelasize = shdr.sh_size;
    } else if(strncmp(name, ".rel.data", 9) == 0) {
      /* using elf32_rel instead of rela */
      using_relas = 0;
      datarelaoff = shdr.sh_offset;
      datarelasize = shdr.sh_size;
    } else if(strncmp(name, ".rela.data", 10) == 0) {
      using_relas = 1;
      datarelaoff = shdr.sh_offset;
      datarelasize = shdr.sh_size;
    } else if(strncmp(name, ".bss", 4) == 0) {
      bsssize = shdr.sh_size;
      bss.number = i;
      bss.offset = 0;
    }

    /* Move on to the next section header. */
    shdrptr += shdrsize;
  }

  if(symtabsize == 0) {
    return ELFLOADER_NO_SYMTAB;
  }
  if(strtabsize == 0) {
    return ELFLOADER_NO_STRTAB;
  }
  if(textsize == 0) {
    return ELFLOADER_NO_TEXT;
  }

  PRINTF("before allocate ram\n");
  bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize);
  data.address = (char *)bss.address + bsssize;
  PRINTF("before allocate rom\n");
  text.address = (char *)elfloader_arch_allocate_rom(textsize + rodatasize);
  rodata.address = (char *)text.address + textsize;
  

  PRINTF("bss base address: bss.address = 0x%08x\n", bss.address);
  PRINTF("data base address: data.address = 0x%08x\n", data.address);
  PRINTF("text base address: text.address = 0x%08x\n", text.address);
  PRINTF("rodata base address: rodata.address = 0x%08x\n", rodata.address);


  /* If we have text segment relocations, we process them. */
  PRINTF("elfloader: relocate text\n");
  if(textrelasize > 0) {
	    ret = relocate_section(fd,
			   textrelaoff, textrelasize,
			   textoff,
			   text.address,
			   strs,
			   strtaboff,
			   symtaboff, symtabsize, using_relas);
    if(ret != ELFLOADER_OK) {
      return ret;
    }
  }

  /* If we have any rodata segment relocations, we process them too. */
  PRINTF("elfloader: relocate rodata\n");
  if(rodatarelasize > 0) {
    ret = relocate_section(fd,
			   rodatarelaoff, rodatarelasize,
			   rodataoff,
			   rodata.address,
			   strs,
			   strtaboff,
			   symtaboff, symtabsize, using_relas);
    if(ret != ELFLOADER_OK) {
      PRINTF("elfloader: data failed\n");
      return ret;
    }
  }

  /* If we have any data segment relocations, we process them too. */
  PRINTF("elfloader: relocate data\n");
  if(datarelasize > 0) {
    ret = relocate_section(fd,
			   datarelaoff, datarelasize,
			   dataoff,
			   data.address,
			   strs,
			   strtaboff,
			   symtaboff, symtabsize, using_relas);
    if(ret != ELFLOADER_OK) {
      PRINTF("elfloader: data failed\n");
      return ret;
    }
  }

  /* Write text and rodata segment into flash and data segment into RAM. */
  elfloader_arch_write_rom(fd, textoff, textsize, text.address);
  elfloader_arch_write_rom(fd, rodataoff, rodatasize, rodata.address);
  
  memset(bss.address, 0, bsssize);
  seek_read(fd, dataoff, data.address, datasize);

  PRINTF("elfloader: autostart search\n");
  process = (struct process **) find_local_symbol(fd, "autostart_processes", symtaboff, symtabsize, strtaboff);
  if(process != NULL) {
    PRINTF("elfloader: autostart found\n");
    elfloader_autostart_processes = process;
    return ELFLOADER_OK;
  } else {
    PRINTF("elfloader: no autostart\n");
    process = (struct process **) find_program_processes(fd, symtaboff, symtabsize, strtaboff);
    if(process != NULL) {
      PRINTF("elfloader: FOUND PRG\n");
    }
    return ELFLOADER_NO_STARTPOINT;
  }
}
Example #18
0
File: fs.c Project: rbkloss/dcc_fs
int fs_write_file(struct superblock *sb, const char *fname, char *buf, size_t cnt) {
    const uint64_t blocksNeeded = MAX(1, cnt / sb->blksz);
    if (blocksNeeded > sb->freeblks) {
        errno = ENOSPC;
        return -1;
    }
    int blocksUsed = 0;

    if (strlen(fname) + 1 > getFileNameMaxLen(sb)) {
        errno = ENAMETOOLONG;
        return -1;
    }

    if (existsFile(sb, fname)) {
        errno = EEXIST;
        return -1;
    }

    int len = 0, exists = 0;
    char** fileParts = getFileParts(fname, &len);
    uint64_t dirBlock = findFile(sb, fname, &exists);
    char* dirName = NULL;
    struct inode* dirNode, *node;
    struct nodeinfo* meta = (struct nodeinfo*) calloc(1, sb->blksz);
    initNode(&dirNode, sb->blksz);
    initNode(&node, sb->blksz);
    seek_read(sb, dirBlock, dirNode);
    seek_read(sb, dirNode->meta, meta);
    dirName = calloc(1, sizeof (char)* (strlen(meta->name) + 1));
    strcpy(dirName, meta->name);

    if (strcmp(fileParts[MAX(0, len - 2)], dirName) != 0) {
        errno = EBADF;
        free(dirName);
        free(node);
        free(meta);
        free(dirNode);
        return -1;
    }


    uint64_t fileBlock = fs_get_block(sb);
    insertInBlock(sb, dirBlock, fileBlock);
    uint64_t blocksList[blocksNeeded];
    ///properly write the file
    while (blocksUsed < blocksNeeded) {
        uint64_t block = fs_get_block(sb);
        blocksList[blocksUsed] = block;
        char* temp = calloc(1, sb->blksz);
        char* blockContent = buf + sb->blksz * (blocksUsed);
        strcpy(temp, blockContent);
        blocksUsed++;
        seek_write(sb, block, temp);
        free(temp);
    }
    strcpy(meta->name, fileParts[len - 1]);
    meta->size = cnt;
    meta->reserved[0] = 0;

    node->meta = fs_get_block(sb);
    node->mode = IMREG;
    node->parent = dirBlock;

    seek_write(sb, node->meta, meta);

    uint64_t nodeBlock = fileBlock;
    blocksUsed = 0;
    while (blocksUsed < blocksNeeded) {
        int i = 0;
        int linksLen = getLinksMaxLen(sb);
        int N = MIN(linksLen, blocksNeeded);
        while (i < N) {
            node->links[i] = blocksList[i];
            i++;
            blocksUsed++;
        }
        if (blocksUsed < blocksNeeded) {
            node->next = fs_get_block(sb);
            seek_write(sb, nodeBlock, node);
            nodeBlock = node->next;
            node->next = 0;
            node->parent = fileBlock;
            node->mode = IMCHILD | IMREG;
            node->meta = fs_get_block(sb);
            strcpy(meta->name, fileParts[len - 1]);
            meta->size = cnt;
            seek_write(sb, node->meta, meta);
        }
    }
    seek_write(sb, nodeBlock, node);

    free(meta);
    free(node);
    freeFileParts(&fileParts, len);
    free(dirNode);
    free(dirName);

    return 0;
}