static status_t get_next_partition(int fd, apple_driver_descriptor &descriptor, uint32 &cookie, apple_partition_map &partition) { uint32 block = cookie; // find first partition map if this is the first call, // or else, just load the next block do { ssize_t bytesRead = read_pos(fd, (off_t)block * descriptor.BlockSize(), (void *)&partition, sizeof(apple_partition_map)); if (bytesRead < (ssize_t)sizeof(apple_partition_map)) return B_ERROR; block++; } while (cookie == 0 && block < 64 && !partition.HasValidSignature()); if (!partition.HasValidSignature()) { if (cookie) return B_ENTRY_NOT_FOUND; // we searched for the first partition map entry and failed return B_ERROR; } // the first partition map entry must be of type Apple_partition_map if (!cookie && (strncmp(partition.type, "Apple_", 6) || strcmp(partition.type + 6, kApplePartitionTypes[0]))) return B_ERROR; // ToDo: warn about unknown types? cookie = block; return B_OK; }
int Image::ReadHeader() { fHeader = new Elf32_Ehdr; if (fHeader == 0) return E_NO_MEMORY; if (read_pos(fFileHandle, 0, fHeader, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)) { printf("incomplete header\n"); return E_NOT_IMAGE; } if (memcmp(fHeader->e_ident, ELF_MAGIC, 4) != 0) { printf("not an elf file\n"); return E_NOT_IMAGE; } if (fHeader->e_ident[4] != ELFCLASS32 || fHeader->e_ident[5] != ELFDATA2LSB) { printf("invalid object type\n"); return E_NOT_IMAGE; } if (fHeader->e_phoff == 0) { printf("file has no program header\n"); return E_NOT_IMAGE; } if (fHeader->e_phentsize < sizeof(Elf32_Phdr)) { printf("File segment info struct is too small!!!\n"); return E_NOT_IMAGE; } return 0; }
/*static*/ status_t ELFLoader<Class>::Create(int fd, preloaded_image** _image) { ImageType* image = (ImageType*)kernel_args_malloc(sizeof(ImageType)); if (image == NULL) return B_NO_MEMORY; ssize_t length = read_pos(fd, 0, &image->elf_header, sizeof(EhdrType)); if (length < (ssize_t)sizeof(EhdrType)) { kernel_args_free(image); return B_BAD_TYPE; } const EhdrType& elfHeader = image->elf_header; if (memcmp(elfHeader.e_ident, ELF_MAGIC, 4) != 0 || elfHeader.e_ident[4] != Class::kIdentClass || elfHeader.e_phoff == 0 || !elfHeader.IsHostEndian() || elfHeader.e_phentsize != sizeof(PhdrType)) { kernel_args_free(image); return B_BAD_TYPE; } image->elf_class = elfHeader.e_ident[EI_CLASS]; *_image = image; return B_OK; }
static float apple_identify_partition(int fd, partition_data *partition, void **_cookie) { struct apple_driver_descriptor *descriptor; uint8 buffer[512]; if (read_pos(fd, 0, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) return B_ERROR; descriptor = (apple_driver_descriptor *)buffer; TRACE(("apple: read first chunk (signature = %x)\n", descriptor->signature)); if (!descriptor->HasValidSignature()) return B_ERROR; TRACE(("apple: valid partition descriptor!\n")); // ToDo: Should probably call get_next_partition() once to know if there // are any partitions on this disk // copy the relevant part of the first block descriptor = new apple_driver_descriptor(); memcpy(descriptor, buffer, sizeof(apple_driver_descriptor)); *_cookie = (void *)descriptor; // ToDo: reevaluate the priority with ISO-9660 and others in mind // (for CD-ROM only, as far as I can tell) return 0.5f; }
int Image::Load(Team &team) { fProgramHeaderTable = new Elf32_Phdr[fHeader->e_phnum]; if (fProgramHeaderTable == 0) return E_NO_MEMORY; if (read_pos(fFileHandle, fHeader->e_phoff, fProgramHeaderTable, fHeader->e_phnum * fHeader->e_phentsize) != fHeader->e_phnum * fHeader->e_phentsize) { printf("Error reading program header\n"); return E_NOT_IMAGE; } const char *filename = fPath; for (const char *c = fPath; *c; c++) if (*c == '/') filename = c + 1; for (int segmentIndex = 0; segmentIndex < fHeader->e_phnum; segmentIndex++) { char areaName[OS_NAME_LENGTH]; snprintf(areaName, OS_NAME_LENGTH, "%.12s seg_%d", filename, segmentIndex); if (fProgramHeaderTable[segmentIndex].p_vaddr % PAGE_SIZE != fProgramHeaderTable[segmentIndex].p_offset % PAGE_SIZE) { printf("Unaligned Segment\n"); return E_NOT_IMAGE; } #if DISABLE_DEMAND_PAGE Area *seg = space->CreateArea(areaName, ((fProgramHeaderTable[segmentIndex].p_memsz + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE, AREA_NOT_LOCKED, USER_READ | SYSTEM_READ | SYSTEM_WRITE, WRITABLE_PAGE, static_cast<void*>(fProgramHeaderTable[segmentIndex].p_vaddr), EXACT_ADDRESS); if (seg == 0) return E_NOT_IMAGE; lseek(fFileHandle, fProgramHeaderTable[segmentIndex].p_offset, SEEK_SET); if (fProgramHeaderTable[segmentIndex].p_type == PT_LOAD && fProgramHeaderTable[segmentIndex].p_filesz > 0) read(fFileHandle, static_cast<void*>(fProgramHeaderTable[segmentIndex].p_vaddr), fProgramHeaderTable[segmentIndex].p_filesz); #else status_t error = CreateFileArea(areaName, fPath, fProgramHeaderTable[segmentIndex].p_vaddr & ~(PAGE_SIZE - 1), fProgramHeaderTable[segmentIndex].p_offset & ~(PAGE_SIZE - 1), ((fProgramHeaderTable[segmentIndex].p_memsz + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE, EXACT_ADDRESS | MAP_PRIVATE, ((fProgramHeaderTable[segmentIndex].p_flags & PF_W) ? (USER_WRITE | SYSTEM_WRITE) : 0) | USER_READ | USER_EXEC | SYSTEM_READ, team); if (error < 0) { printf("Failed to map image file\n"); return error; } #endif if (segmentIndex == 0) fBaseAddress = reinterpret_cast<void*>(fProgramHeaderTable[segmentIndex].p_vaddr); } return 0; }
Directory::Directory(Volume &volume, int32 block) : fVolume(volume) { void *data = malloc(volume.BlockSize()); if (data == NULL) return; if (read_pos(volume.Device(), block * volume.BlockSize(), data, volume.BlockSize()) == volume.BlockSize()) fNode.SetTo(data, volume.BlockSize()); }
ssize_t build_platform_read_pos(int fd, fs_off_t pos, void *buf, size_t count) { ssize_t result = read_pos(fd, pos, buf, count); if (result < 0) { errno = from_platform_error(errno); return -1; } return result; }
status_t Header::_Read(int fd, off_t offset, void* data, size_t size) const { ssize_t bytesRead = read_pos(fd, offset, data, size); if (bytesRead < 0) return bytesRead; if (bytesRead != (ssize_t)size) return B_IO_ERROR; return B_OK; }
// Read status_t FileHandle::Read(off_t pos, void* buffer, size_t size, size_t* _bytesRead) { if (fFD < 0) return B_BAD_VALUE; ssize_t bytesRead = read_pos(fFD, pos, buffer, size); if (bytesRead < 0) return errno; *_bytesRead = bytesRead; return B_OK; }
/*static*/ status_t Volume::Identify(int fd, disk_super_block* superBlock) { uint8 buffer[1024]; if (read_pos(fd, 0, buffer, sizeof(buffer)) != sizeof(buffer)) return B_IO_ERROR; uint32 offset; if (CheckSuperBlock(buffer, &offset) != B_OK) return B_BAD_VALUE; memcpy(superBlock, buffer + offset, sizeof(disk_super_block)); return B_OK; }
float fs_identify_partition(int fd, partition_data *partition, void **_cookie) { NTFS_BOOT_SECTOR boot; identify_cookie *cookie; ntfs_volume *ntVolume; uint8 *buf = (uint8*)&boot; char devpath[256]; // read in the boot sector ERRPRINT("fs_identify_partition: read in the boot sector\n"); if (read_pos(fd, 0, (void*)&boot, 512) != 512) { return -1; } // check boot signature if ((buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) && buf[0x15] == 0xf8) return -1; // check boot signature NTFS if (memcmp(buf + 3, "NTFS ", 8) != 0) return -1; // get path for device if (!ioctl(fd, B_GET_PATH_FOR_DEVICE, devpath)) return -1; // try mount ntVolume = utils_mount_volume(devpath, MS_RDONLY, true); if (!ntVolume) return -1; // allocate identify_cookie cookie = (identify_cookie *)malloc(sizeof(identify_cookie)); if (!cookie) return -1; memcpy(&cookie->boot, &boot, 512); strcpy(cookie->label, "NTFS Volume"); if (ntVolume->vol_name && ntVolume->vol_name[0] != '\0') strcpy(cookie->label, ntVolume->vol_name); ntfs_umount(ntVolume, true); *_cookie = cookie; return 0.8f; }
ssize_t Partition::ReadAt(void *cookie, off_t position, void *buffer, size_t bufferSize) { if (position > this->size) return 0; if (position < 0) return B_BAD_VALUE; if (position + bufferSize > this->size) bufferSize = this->size - position; ssize_t result = read_pos(fFD, this->offset + position, buffer, bufferSize); return result < 0 ? errno : result; }
/*static*/ status_t Volume::Identify(int fd, exfat_super_block* superBlock) { if (read_pos(fd, EXFAT_SUPER_BLOCK_OFFSET, superBlock, sizeof(exfat_super_block)) != sizeof(exfat_super_block)) return B_IO_ERROR; if (!superBlock->IsValid()) { ERROR("invalid superblock!\n"); return B_BAD_VALUE; } return B_OK; }
/*static*/ status_t Volume::Identify(int fd, ext2_super_block* superBlock) { if (read_pos(fd, EXT2_SUPER_BLOCK_OFFSET, superBlock, sizeof(ext2_super_block)) != sizeof(ext2_super_block)) return B_IO_ERROR; if (!superBlock->IsValid()) { FATAL("invalid super block!\n"); return B_BAD_VALUE; } return _UnsupportedIncompatibleFeatures(*superBlock) == 0 ? B_OK : B_UNSUPPORTED; }
status_t BJoystick::Update() { CALLED(); if (fJoystickInfo == NULL || fJoystickData == NULL || fFD < 0) return B_NO_INIT; for (uint16 i = 0; i < fJoystickInfo->module_info.num_sticks; i++) { variable_joystick *values = (variable_joystick *)fJoystickData->ItemAt(i); if (values == NULL) return B_NO_INIT; ssize_t result = read_pos(fFD, i, values->data, values->data_size); if (result < 0) return result; if ((size_t)result != values->data_size) return B_ERROR; if (i > 0) continue; // fill in the legacy values for the first stick timestamp = *values->timestamp; if (values->axis_count >= 1) horizontal = values->axes[0]; else horizontal = 0; if (values->axis_count >= 2) vertical = values->axes[1]; else vertical = 0; if (values->button_blocks > 0) { button1 = (*values->buttons & 1) == 0; button2 = (*values->buttons & 2) == 0; } else { button1 = true; button2 = true; } } return B_OK; }
/*! Computes a check sum for the specified block. The check sum is the sum of all data in that block interpreted as an array of uint32 values. Note, this must use the same method as the one used in boot/platform/bios_ia32/devices.cpp (or similar solutions). */ static uint32 compute_check_sum(KDiskDevice* device, off_t offset) { char buffer[512]; ssize_t bytesRead = read_pos(device->FD(), offset, buffer, sizeof(buffer)); if (bytesRead < B_OK) return 0; if (bytesRead < (ssize_t)sizeof(buffer)) memset(buffer + bytesRead, 0, sizeof(buffer) - bytesRead); uint32* array = (uint32*)buffer; uint32 sum = 0; for (uint32 i = 0; i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) { sum += array[i]; } return sum; }
int main(int argc, char **argv) { int frame; char name[128]; char gname[128]; vect_t normal; struct wmember head, ghead; matp_t matp; mat_t xlate; mat_t rot1, rot2, rot3; vect_t from, to; vect_t offset; if (argc > 0) { bu_log("Usage: %s\n", argv[0]); bu_log(" (Program expects ./pos.dat file to be present)\n"); bu_log(" (Will generate file tube.g)\n"); if (argc == 2) { if ( BU_STR_EQUAL(argv[1],"-h") || BU_STR_EQUAL(argv[1],"-?")) bu_exit(1,NULL); } else if (argc == 1) bu_log(" Program continues running:\n"); } BU_LIST_INIT(&head.l); BU_LIST_INIT(&ghead.l); outfp = wdb_fopen("tube.g"); if ((pos_fp = fopen("pos.dat", "r")) == NULL) perror("pos.dat"); /* Just warn */ mk_id(outfp, "Procedural Gun Tube with Projectile"); VSET(normal, 0, -1, 0); mk_half(outfp, "cut", normal, 0.0); VSET(normal, 0, 1, 0); mk_half(outfp, "bg.s", normal, -1000.0); (void)mk_addmember("bg.s", &head.l, NULL, WMOP_UNION); /* temp use of "head" */ mk_lcomb(outfp, "bg.r", &head, 1, "texture", "file=movie128bw.pix w=128", (unsigned char *)0, 0); #ifdef never /* Numbers for a 105-mm M68 gun */ oradius = 5 * inches2mm / 2; /* 5" outer diameter */ iradius = 4.134 * inches2mm / 2; /* 5" inner (land) diameter */ #else /* Numbers invented to match 125-mm KE (Erline) round */ iradius = 125.0/2; oradius = iradius + (5-4.134) * inches2mm / 2; /* 5" outer diameter */ #endif fprintf(stderr, "inner radius=%gmm, outer radius=%gmm\n", iradius, oradius); length = 187.0 * inches2mm; #ifdef never spacing = 100.; /* mm per sample */ nsamples = ceil(length/spacing); fprintf(stderr, "length=%gmm, spacing=%gmm\n", length, spacing); fprintf(stderr, "nframes=%d\n", nframes); #endif for (frame=0;; frame++) { cur_time = frame * delta_t; #ifdef never /* Generate some dummy sample data */ if (frame < 16) break; for (i=0; i<nsamples; i++) { sample[i][X] = i * spacing; sample[i][Y] = 0; sample[i][Z] = 4 * oradius * sin( ((double)i*i)/nsamples * M_2PI + frame * M_PI_4); } projectile_pos = ((double)frame)/nframes * (sample[nsamples-1][X] - sample[0][X]); /* length */ #else if (read_frame(stdin) < 0) break; if (pos_fp != NULL) read_pos(pos_fp); #endif #define build_spline build_cyl sprintf(name, "tube%do", frame); build_spline(name, nsamples, oradius); (void)mk_addmember(name, &head.l, NULL, WMOP_UNION); sprintf(name, "tube%di", frame); build_spline(name, nsamples, iradius); mk_addmember(name, &head.l, NULL, WMOP_SUBTRACT); mk_addmember("cut", &head.l, NULL, WMOP_SUBTRACT); sprintf(name, "tube%d", frame); mk_lcomb(outfp, name, &head, 1, "plastic", "", (unsigned char *)0, 0); /* Place the tube region and the ammo together. * The origin of the ammo is expected to be the center * of the rearmost plate. */ mk_addmember(name, &ghead.l, NULL, WMOP_UNION); matp = mk_addmember("ke", &ghead.l, NULL, WMOP_UNION)->wm_mat; VSET(from, 0, -1, 0); VSET(to, 1, 0, 0); /* to X axis */ bn_mat_fromto(rot1, from, to, &outfp->wdb_tol); VSET(from, 1, 0, 0); /* Projectile is 480mm long -- use center pt, not end */ xfinddir(to, projectile_pos + 480.0/2, offset); bn_mat_fromto(rot2, from, to, &outfp->wdb_tol); MAT_IDN(xlate); MAT_DELTAS_VEC(xlate, offset); bn_mat_mul(rot3, rot2, rot1); bn_mat_mul(matp, xlate, rot3); (void)mk_addmember("light.r", &ghead.l, NULL, WMOP_UNION); (void)mk_addmember("bg.r", &ghead.l, NULL, WMOP_UNION); sprintf(gname, "g%d", frame); mk_lcomb(outfp, gname, &ghead, 0, (char *)0, "", (unsigned char *)0, 0); fprintf(stderr, "frame %d\n", frame); fflush(stderr); } wdb_close(outfp); fflush(stderr); return 0; }
status_t ISOMount(const char *path, uint32 flags, iso9660_volume **_newVolume, bool allowJoliet) { // path: path to device (eg, /dev/disk/scsi/030/raw) // partition: partition number on device ???? // flags: currently unused // determine if it is an ISO volume. char buffer[ISO_PVD_SIZE]; bool done = false; bool isISO = false; off_t offset = 0x8000; ssize_t retval; partition_info partitionInfo; int deviceBlockSize, multiplier; iso9660_volume *volume; (void)flags; TRACE(("ISOMount - ENTER\n")); volume = (iso9660_volume *)calloc(sizeof(iso9660_volume), 1); if (volume == NULL) { TRACE(("ISOMount - mem error \n")); return B_NO_MEMORY; } memset(&partitionInfo, 0, sizeof(partition_info)); /* open and lock the device */ volume->fdOfSession = open(path, O_RDONLY); /* try to open the raw device to get access to the other sessions as well */ if (volume->fdOfSession >= 0) { if (ioctl(volume->fdOfSession, B_GET_PARTITION_INFO, &partitionInfo) < 0) { TRACE(("B_GET_PARTITION_INFO: ioctl returned error\n")); strcpy(partitionInfo.device, path); } TRACE(("ISOMount: open device/file \"%s\"\n", partitionInfo.device)); volume->fd = open(partitionInfo.device, O_RDONLY); } if (volume->fdOfSession < 0 || volume->fd < 0) { close(volume->fd); close(volume->fdOfSession); TRACE(("ISO9660 ERROR - Unable to open <%s>\n", path)); free(volume); return B_BAD_VALUE; } deviceBlockSize = get_device_block_size(volume->fdOfSession); if (deviceBlockSize < 0) { TRACE(("ISO9660 ERROR - device block size is 0\n")); close(volume->fd); close(volume->fdOfSession); free(volume); return B_BAD_VALUE; } volume->joliet_level = 0; while (!done && offset < 0x10000) { retval = read_pos(volume->fdOfSession, offset, (void*)buffer, ISO_PVD_SIZE); if (retval < ISO_PVD_SIZE) { isISO = false; break; } if (strncmp(buffer + 1, kISO9660IDString, 5) == 0) { if (*buffer == 0x01 && !isISO) { // ISO_VD_PRIMARY off_t maxBlocks; TRACE(("ISOMount: Is an ISO9660 volume, initting rec\n")); InitVolDesc(volume, buffer); strncpy(volume->devicePath,path,127); volume->id = ISO_ROOTNODE_ID; TRACE(("ISO9660: volume->blockSize = %d\n", volume->logicalBlkSize[FS_DATA_FORMAT])); multiplier = deviceBlockSize / volume->logicalBlkSize[FS_DATA_FORMAT]; TRACE(("ISOMount: block size multiplier is %d\n", multiplier)); // if the session is on a real device, size != 0 if (partitionInfo.size != 0) { maxBlocks = (partitionInfo.size + partitionInfo.offset) / volume->logicalBlkSize[FS_DATA_FORMAT]; } else maxBlocks = volume->volSpaceSize[FS_DATA_FORMAT]; /* Initialize access to the cache so that we can do cached i/o */ TRACE(("ISO9660: cache init: dev %d, max blocks %Ld\n", volume->fd, maxBlocks)); volume->fBlockCache = block_cache_create(volume->fd, maxBlocks, volume->logicalBlkSize[FS_DATA_FORMAT], true); isISO = true; } else if (*buffer == 0x02 && isISO && allowJoliet) { // ISO_VD_SUPPLEMENTARY // JOLIET extension // test escape sequence for level of UCS-2 characterset if (buffer[88] == 0x25 && buffer[89] == 0x2f) { switch (buffer[90]) { case 0x40: volume->joliet_level = 1; break; case 0x43: volume->joliet_level = 2; break; case 0x45: volume->joliet_level = 3; break; } TRACE(("ISO9660 Extensions: Microsoft Joliet Level %d\n", volume->joliet_level)); // Because Joliet-stuff starts at other sector, // update root directory record. if (volume->joliet_level > 0) { InitNode(volume, &volume->rootDirRec, &buffer[156], NULL); } } } else if (*(unsigned char *)buffer == 0xff) { // ISO_VD_END done = true; } else TRACE(("found header %d\n",*buffer)); } offset += 0x800; } if (!isISO) { // It isn't an ISO disk. close(volume->fdOfSession); close(volume->fd); free(volume); TRACE(("ISOMount: Not an ISO9660 volume!\n")); return B_BAD_VALUE; } TRACE(("ISOMount - EXIT, returning %p\n", volume)); *_newVolume = volume; return B_OK; }
/*static*/ status_t ELFLoader<Class>::_LoadSymbolTable(int fd, ImageType* image) { const EhdrType& elfHeader = image->elf_header; SymType* symbolTable = NULL; ShdrType* stringHeader = NULL; uint32 numSymbols = 0; char* stringTable; status_t status; // get section headers ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize; ShdrType* sectionHeaders = (ShdrType*)malloc(size); if (sectionHeaders == NULL) { dprintf("error allocating space for section headers\n"); return B_NO_MEMORY; } ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size); if (length < size) { TRACE(("error reading in program headers\n")); status = B_ERROR; goto error1; } // find symbol table in section headers for (int32 i = 0; i < elfHeader.e_shnum; i++) { if (sectionHeaders[i].sh_type == SHT_SYMTAB) { stringHeader = §ionHeaders[sectionHeaders[i].sh_link]; if (stringHeader->sh_type != SHT_STRTAB) { TRACE(("doesn't link to string table\n")); status = B_BAD_DATA; goto error1; } // read in symbol table size = sectionHeaders[i].sh_size; symbolTable = (SymType*)kernel_args_malloc(size); if (symbolTable == NULL) { status = B_NO_MEMORY; goto error1; } length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size); if (length < size) { TRACE(("error reading in symbol table\n")); status = B_ERROR; goto error1; } numSymbols = size / sizeof(SymType); break; } } if (symbolTable == NULL) { TRACE(("no symbol table\n")); status = B_BAD_VALUE; goto error1; } // read in string table size = stringHeader->sh_size; stringTable = (char*)kernel_args_malloc(size); if (stringTable == NULL) { status = B_NO_MEMORY; goto error2; } length = read_pos(fd, stringHeader->sh_offset, stringTable, size); if (length < size) { TRACE(("error reading in string table\n")); status = B_ERROR; goto error3; } TRACE(("loaded %ld debug symbols\n", numSymbols)); // insert tables into image image->debug_symbols = symbolTable; image->num_debug_symbols = numSymbols; image->debug_string_table = stringTable; image->debug_string_table_size = size; free(sectionHeaders); return B_OK; error3: kernel_args_free(stringTable); error2: kernel_args_free(symbolTable); error1: free(sectionHeaders); return status; }
/*static*/ status_t ELFLoader<Class>::Load(int fd, preloaded_image* _image) { size_t totalSize; ssize_t length; status_t status; void* mappedRegion = NULL; ImageType* image = static_cast<ImageType*>(_image); const EhdrType& elfHeader = image->elf_header; ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize; PhdrType* programHeaders = (PhdrType*)malloc(size); if (programHeaders == NULL) { dprintf("error allocating space for program headers\n"); status = B_NO_MEMORY; goto error1; } length = read_pos(fd, elfHeader.e_phoff, programHeaders, size); if (length < size) { TRACE(("error reading in program headers\n")); status = B_ERROR; goto error1; } // create an area large enough to hold the image image->data_region.size = 0; image->text_region.size = 0; for (int32 i = 0; i < elfHeader.e_phnum; i++) { PhdrType& header = programHeaders[i]; switch (header.p_type) { case PT_LOAD: break; case PT_DYNAMIC: image->dynamic_section.start = header.p_vaddr; image->dynamic_section.size = header.p_memsz; continue; case PT_INTERP: case PT_PHDR: case PT_ARM_UNWIND: // known but unused type continue; default: dprintf("unhandled pheader type 0x%" B_PRIx32 "\n", header.p_type); continue; } RegionType* region; if (header.IsReadWrite()) { if (image->data_region.size != 0) { dprintf("elf: rw already handled!\n"); continue; } region = &image->data_region; } else if (header.IsExecutable()) { if (image->text_region.size != 0) { dprintf("elf: ro already handled!\n"); continue; } region = &image->text_region; } else continue; region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE); region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); region->delta = -region->start; TRACE(("segment %ld: start = 0x%llx, size = %llu, delta = %llx\n", i, (uint64)region->start, (uint64)region->size, (int64)(AddrType)region->delta)); } // found both, text and data? if (image->data_region.size == 0 || image->text_region.size == 0) { dprintf("Couldn't find both text and data segment!\n"); status = B_BAD_DATA; goto error1; } // get the segment order RegionType* firstRegion; RegionType* secondRegion; if (image->text_region.start < image->data_region.start) { firstRegion = &image->text_region; secondRegion = &image->data_region; } else { firstRegion = &image->data_region; secondRegion = &image->text_region; } // The kernel and the modules are relocatable, thus AllocateRegion() // can automatically allocate an address, but shall prefer the specified // base address. totalSize = secondRegion->start + secondRegion->size - firstRegion->start; if (Class::AllocateRegion(&firstRegion->start, totalSize, B_READ_AREA | B_WRITE_AREA, &mappedRegion) != B_OK) { status = B_NO_MEMORY; goto error1; } // initialize the region pointers to the allocated region secondRegion->start += firstRegion->start + firstRegion->delta; image->data_region.delta += image->data_region.start; image->text_region.delta += image->text_region.start; TRACE(("text: start 0x%llx, size 0x%llx, delta 0x%llx\n", (uint64)image->text_region.start, (uint64)image->text_region.size, (int64)(AddrType)image->text_region.delta)); TRACE(("data: start 0x%llx, size 0x%llx, delta 0x%llx\n", (uint64)image->data_region.start, (uint64)image->data_region.size, (int64)(AddrType)image->data_region.delta)); // load program data for (int32 i = 0; i < elfHeader.e_phnum; i++) { PhdrType& header = programHeaders[i]; if (header.p_type != PT_LOAD) continue; RegionType* region; if (header.IsReadWrite()) region = &image->data_region; else if (header.IsExecutable()) region = &image->text_region; else continue; TRACE(("load segment %ld (%llu bytes) mapped at %p...\n", i, (uint64)header.p_filesz, Class::Map(region->start))); length = read_pos(fd, header.p_offset, Class::Map(region->start + (header.p_vaddr % B_PAGE_SIZE)), header.p_filesz); if (length < (ssize_t)header.p_filesz) { status = B_BAD_DATA; dprintf("error reading in seg %" B_PRId32 "\n", i); goto error2; } // Clear anything above the file size (that may also contain the BSS // area) uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz; if (offset < region->size) memset(Class::Map(region->start + offset), 0, region->size - offset); } // offset dynamic section, and program entry addresses by the delta of the // regions image->dynamic_section.start += image->text_region.delta; image->elf_header.e_entry += image->text_region.delta; image->num_debug_symbols = 0; image->debug_symbols = NULL; image->debug_string_table = NULL; if (sLoadElfSymbols) _LoadSymbolTable(fd, image); free(programHeaders); return B_OK; error2: if (mappedRegion != NULL) platform_free_region(mappedRegion, totalSize); error1: free(programHeaders); kernel_args_free(image); return status; }
status_t elf_load_image(int fd, preloaded_image *image) { size_t totalSize; status_t status; TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image)); struct Elf32_Ehdr &elfHeader = image->elf_header; ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr)); if (length < (ssize_t)sizeof(Elf32_Ehdr)) return B_BAD_TYPE; status = verify_elf_header(elfHeader); if (status < B_OK) return status; ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize; Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size); if (programHeaders == NULL) { dprintf("error allocating space for program headers\n"); return B_NO_MEMORY; } length = read_pos(fd, elfHeader.e_phoff, programHeaders, size); if (length < size) { TRACE(("error reading in program headers\n")); status = B_ERROR; goto error1; } // create an area large enough to hold the image image->data_region.size = 0; image->text_region.size = 0; for (int32 i = 0; i < elfHeader.e_phnum; i++) { Elf32_Phdr &header = programHeaders[i]; switch (header.p_type) { case PT_LOAD: break; case PT_DYNAMIC: image->dynamic_section.start = header.p_vaddr; image->dynamic_section.size = header.p_memsz; continue; case PT_INTERP: case PT_PHDR: // known but unused type continue; default: dprintf("unhandled pheader type 0x%lx\n", header.p_type); continue; } elf_region *region; if (header.IsReadWrite()) { if (image->data_region.size != 0) { dprintf("elf: rw already handled!\n"); continue; } region = &image->data_region; } else if (header.IsExecutable()) { if (image->text_region.size != 0) { dprintf("elf: ro already handled!\n"); continue; } region = &image->text_region; } else continue; region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE); region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); region->delta = -region->start; TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i, region->start, region->size, region->delta)); } // found both, text and data? if (image->data_region.size == 0 || image->text_region.size == 0) { dprintf("Couldn't find both text and data segment!\n"); status = B_BAD_DATA; goto error1; } // get the segment order elf_region *firstRegion; elf_region *secondRegion; if (image->text_region.start < image->data_region.start) { firstRegion = &image->text_region; secondRegion = &image->data_region; } else { firstRegion = &image->data_region; secondRegion = &image->text_region; } // Check whether the segments have an unreasonable amount of unused space // inbetween. totalSize = secondRegion->start + secondRegion->size - firstRegion->start; if (totalSize > image->text_region.size + image->data_region.size + 8 * 1024) { status = B_BAD_DATA; goto error1; } // The kernel and the modules are relocatable, thus // platform_allocate_region() can automatically allocate an address, // but shall prefer the specified base address. if (platform_allocate_region((void **)&firstRegion->start, totalSize, B_READ_AREA | B_WRITE_AREA, false) < B_OK) { status = B_NO_MEMORY; goto error1; } // initialize the region pointers to the allocated region secondRegion->start += firstRegion->start + firstRegion->delta; image->data_region.delta += image->data_region.start; image->text_region.delta += image->text_region.start; // load program data for (int i = 0; i < elfHeader.e_phnum; i++) { Elf32_Phdr &header = programHeaders[i]; if (header.p_type != PT_LOAD) continue; elf_region *region; if (header.IsReadWrite()) region = &image->data_region; else if (header.IsExecutable()) region = &image->text_region; else continue; TRACE(("load segment %d (%ld bytes)...\n", i, header.p_filesz)); length = read_pos(fd, header.p_offset, (void *)(region->start + (header.p_vaddr % B_PAGE_SIZE)), header.p_filesz); if (length < (ssize_t)header.p_filesz) { status = B_BAD_DATA; dprintf("error reading in seg %d\n", i); goto error2; } // Clear anything above the file size (that may also contain the BSS // area) uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz; if (offset < region->size) memset((void *)(region->start + offset), 0, region->size - offset); } // offset dynamic section, and program entry addresses by the delta of the // regions image->dynamic_section.start += image->text_region.delta; image->elf_header.e_entry += image->text_region.delta; image->num_debug_symbols = 0; image->debug_symbols = NULL; image->debug_string_table = NULL; if (sLoadElfSymbols) load_elf_symbol_table(fd, image); free(programHeaders); return B_OK; error2: if (image->text_region.start != 0) platform_free_region((void *)image->text_region.start, totalSize); error1: free(programHeaders); return status; }
status_t VolumeCryptContext::_Detect(int fd, off_t offset, off_t size, const uint8* key, uint32 keyLength, uint8* buffer, true_crypt_header& header) { ssize_t bytesRead = read_pos(fd, offset, buffer, BLOCK_SIZE); if (bytesRead != BLOCK_SIZE) return bytesRead < 0 ? errno : B_IO_ERROR; // decrypt header first uint8* encryptedHeader = buffer + PKCS5_SALT_SIZE; uint8* salt = buffer; uint8 diskKey[DISK_KEY_SIZE]; derive_key(key, keyLength, salt, PKCS5_SALT_SIZE, diskKey, DISK_KEY_SIZE); //dprintf("salt %x, key %x\n", *(int*)salt, *(int*)diskKey); status_t status = Init(ALGORITHM_AES, MODE_XTS, diskKey, DISK_KEY_SIZE); if (status != B_OK) return status; memcpy(&header, encryptedHeader, sizeof(true_crypt_header)); Decrypt((uint8*)&header, sizeof(true_crypt_header)); if (!valid_true_crypt_header(header)) { dump_true_crypt_header(header); // Try with legacy encryption mode LRW instead status = Init(ALGORITHM_AES, MODE_LRW, diskKey, DISK_KEY_SIZE); if (status != B_OK) return status; memcpy(&header, encryptedHeader, sizeof(true_crypt_header)); Decrypt((uint8*)&header, sizeof(true_crypt_header)); if (!valid_true_crypt_header(header)) { dump_true_crypt_header(header); return B_PERMISSION_DENIED; } } if (header.RequiredProgramVersion() >= 0x700) { // TODO: test if the block size is really not 512 bytes dprintf("header version not yet supported!\n"); return B_NOT_SUPPORTED; } // then init context with the keys from the unencrypted header SetKey(header.disk_key, sizeof(header.disk_key)); if (offset != 0) { // this is a hidden drive, take over the size from the header fSize = B_BENDIAN_TO_HOST_INT64(header.hidden_size); fOffset = offset - fSize; fHidden = true; } else { fOffset = BLOCK_SIZE; fSize = size - BLOCK_SIZE; fHidden = false; } if (header.Version() >= 4) { fOffset = header.EncryptedOffset(); fSize = header.EncryptedSize(); } fMode->SetBlockOffset(fOffset / BLOCK_SIZE); return B_OK; }
void read_sphere(const int fd, union u_o *const u) { read_pos(fd, &(u->sphere.point)); u->sphere.point[W] = 1.0f; u->sphere.radius = read_float(fd, '|'); }
void read_value(char *name, char *value) { //The *name and *value are derived from sargv which is given one by one through //a loop from conf_init() if (name != NULL && value != NULL) { if (name[0] == '#') return; g_strstrip(name); g_strstrip(value); if (!strcmp("font", name) || !strcmp("-fn", name)) strcpy(_font, value); else if (!strcmp("background", name) || !strcmp("-bg", name)) { if (!parse_hex_color(value, &_bg)) gdk_color_parse("black", &_bg); } else if (!strcmp("foreground", name) || !strcmp("-fg", name)) { if (!parse_hex_color(value, &_fg)) gdk_color_parse("white", &_fg); } else if (!strcmp("scrollbar", name) || !strcmp("-s", name)) { if (!strcmp(value, "true")) _scrollpos = POS_RIGHT; else if (!strcmp(value, "left")) _scrollpos = POS_LEFT; else if (!strcmp(value, "right")) _scrollpos = POS_RIGHT; else _scrollpos = -1; } else if (!strcmp("border", name) || !strcmp("-b", name)) set_border(value); else if (!strcmp("opacity", name) || !strcmp("-o", name)) _opacity = atof(value); else if (!strcmp("bgimage", name) || !strcmp("-bgimg", name)) strcpy(_bgimage, value); else if (!strcmp("width", name) || !strcmp("-w", name)) _width = atoi(value); else if (!strcmp("height", name) || !strcmp("-h", name)) _height = atoi(value); else if (!strcmp("position", name) || !strcmp("-p", name)) set_pos(value); else if (!strcmp("mod", name) || !strcmp("-m", name)) set_mod(value); else if (!strcmp("key", name) || !strcmp("-k", name)) set_key(value); else if (!strcmp("shell", name) || !strcmp("-sh", name)) strcpy(_shell, value); else if (!strcmp("lines", name) || !strcmp("-l", name)) _lines = atoi(value); else if (!strcmp("showtab", name) || !strcmp("-showtab", name)) { if (!strcasecmp(value, "always")) _showtab = TABS_ALWAYS; else if (!strcasecmp(value, "never")) _showtab = TABS_NEVER; } else if (!strcmp("tabpos", name) || !strcmp("-tabpos", name)) _tabpos = read_pos(value); else if (!strcmp("tablabel", name) || !strcmp("-tablabel", name)) strcpy(_termname, value); else if (!strcmp("cursorblink", name) || !strcmp("-cb", name)) set_cursor_blink(value); else if (!strcmp("cursorshape", name) || !strcmp("-cs", name)) set_cursor_shape(value); else if (g_str_has_prefix(name, "color") || g_str_has_prefix(name, "-c")) { g_strcanon(name, "0123456789", ' '); g_strchug(name); parse_hex_color(value, &_palette[atoi(name)]); read_colors++; } else if (!strcmp("tabfill", name) || !strcmp("-tf", name)) _tabfill = parse_bool_str(value, _tabfill); else if (!strcmp("allowbold", name) || !strcmp("-ab", name)) _allowbold = parse_bool_str(value, _allowbold); else if (!strcmp("keymod", name) || !strcmp("-km", name)) { char **list; list = g_strsplit_set(value, "+", -1); GdkModifierType tmp = 0; int i = 0; while (list[i] != NULL) tmp = tmp | parse_mod(list[i++]); g_strfreev(list); if (tmp != 0) _keymod = tmp; } else if (!strcmp("autohide", name) || !strcmp("-ah", name)) _autohide = parse_bool_str(value, _autohide); else if (!strcmp("scroll", name) || !strcmp("-sc", name)) _scrolloutput = parse_bool_str(value, _scrolloutput); else if (!strcmp("bell", name) || !strcmp("-bell", name)) if (!strcasecmp(value, "false")) _bell = FALSE; } }