size_t Resampler::Transmit48kM(size_t size) { assert(size <= mSink->GetSinkBufferSize()); const int16_t *__restrict__ src __attribute__((align_value(MEM_ALIGN))) = mBuffer; float *__restrict__ sink = mSink->GetBuffer(); size_t p = 0; // processed if (mHead > 0) { if (size < mHead) { Proc48kM(src, sink, size); Shift(size); return size; } else { Proc48kM(src, sink, mHead); p += mHead; mHead = 0; } } for (; ;) { const size_t remain = size - p; const size_t srcSize = remain < mBufferSize ? remain : mBufferSize; if (srcSize == 0) { break; } const size_t transmitted = mSrc->Transmit(srcSize); if (transmitted == 0) { break; } Proc48kM(src, &sink[p], transmitted); p += transmitted; } return p; }
size_t Resampler::Receive48kM(size_t size) { mHead += size; assert(mHead <= mBufferSize); const int16_t *__restrict__ src __attribute__((align_value(MEM_ALIGN))) = mBuffer; size_t p = 0; // processed; for (; ;) { const size_t remain = mHead - p; const size_t sinkSize = remain < mSink->GetSinkBufferSize() ? remain : mSink->GetSinkBufferSize(); if (sinkSize == 0) { break; } float *__restrict__ sink = mSink->GetBuffer(); Proc48kM(&src[p], sink, sinkSize); const size_t received = mSink->Receive(sinkSize); if (received == 0) { break; } p += received; } Shift(p); return p; }
void chip_align(chipaddr *chip) { int align; switch(chip->chip) { case chip_none: case chip_max: align = 1; break; case chip_cart: align = 2; break; case chip_bram: align = 2; break; case chip_zram: case chip_zstk: align = 1; break; case chip_vram: align = 32; break; case chip_cram: align = 32; break; case chip_ram: case chip_mstk: align = 2; break; case chip_pram: case chip_sstk: align = 2; break; case chip_wram: align = 2; break; case chip_pcm: align = 1; break; } chip->addr = align_value(chip->addr, align); }
// _ReadHeader void ResourceFile::_ReadHeader() { // read the header resources_header header; read_exactly(fFile, 0, &header, kResourcesHeaderSize, "Failed to read the header."); // check the header // magic uint32 magic = _GetUInt32(header.rh_resources_magic); if (magic == kResourcesHeaderMagic) { // everything is fine } else if (B_SWAP_INT32(magic) == kResourcesHeaderMagic) { const char* endianessStr[2] = { "little", "big" }; int32 endianess = (fHostEndianess == ((bool)B_HOST_IS_LENDIAN ? 0 : 1)); Warnings::AddCurrentWarning("Endianess seems to be %s, although %s " "was expected.", endianessStr[1 - endianess], endianessStr[endianess]); fHostEndianess = !fHostEndianess; } else throw Exception("Invalid resources header magic."); // resource count uint32 resourceCount = _GetUInt32(header.rh_resource_count); if (resourceCount > kMaxResourceCount) throw Exception("Bad number of resources."); // index section offset uint32 indexSectionOffset = _GetUInt32(header.rh_index_section_offset); if (indexSectionOffset != kResourceIndexSectionOffset) { throw Exception("Unexpected resource index section offset. Is: %lu, " "should be: %lu.", indexSectionOffset, kResourceIndexSectionOffset); } // admin section size uint32 indexSectionSize = kResourceIndexSectionHeaderSize + kResourceIndexEntrySize * resourceCount; indexSectionSize = align_value(indexSectionSize, kResourceIndexSectionAlignment); uint32 adminSectionSize = _GetUInt32(header.rh_admin_section_size); if (adminSectionSize != indexSectionOffset + indexSectionSize) { throw Exception("Unexpected resource admin section size. Is: %lu, " "should be: %lu.", adminSectionSize, indexSectionOffset + indexSectionSize); } // set the resource count fResourceCount = resourceCount; }
// GetResourcesSize uint32 ResourceFile::GetResourcesSize() const { if (!fInfoTableItem || fFile.InitCheck()) throw Exception("Resource file not initialized."); // header uint32 size = kResourcesHeaderSize; // index section uint32 indexSectionSize = kResourceIndexSectionHeaderSize + fResourceCount * kResourceIndexEntrySize; indexSectionSize = align_value(indexSectionSize, kResourceIndexSectionAlignment); size += indexSectionSize; // unknown section size += kUnknownResourceSectionSize; // data uint32 dataSize = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); dataSize += item->GetSize(); } size += dataSize; // info table uint32 infoTableSize = 0; type_code type = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); if (i == 0 || type != item->GetType()) { if (i != 0) infoTableSize += kResourceInfoSeparatorSize; type = item->GetType(); infoTableSize += kMinResourceInfoBlockSize; } else infoTableSize += kMinResourceInfoSize; uint32 nameLen = strlen(item->GetName()); if (nameLen != 0) infoTableSize += nameLen + 1; } infoTableSize += kResourceInfoSeparatorSize + kResourceInfoTableEndSize; size += infoTableSize; return size; }
// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" // RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" #include <stdlib.h> char *passthrough(__attribute__((align_value(0x8000))) char *x) { return x; } int main(int argc, char* argv[]) { char *ptr = (char *)malloc(2); passthrough(ptr + 1); // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:10: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:34: note: alignment assumption was specified here // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte // FIXME: shouldn't there be an assumption on the caller's side too? free(ptr); return 0; }
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s typedef double * __attribute__((align_value(64))) aligned_double; void foo(aligned_double x, double * y __attribute__((align_value(32))), double & z __attribute__((align_value(128)))) { }; // CHECK: define void @_Z3fooPdS_Rd(double* align 64 %x, double* align 32 %y, double* align 128 dereferenceable(8) %z) struct ad_struct { aligned_double a; }; double *foo(ad_struct& x) { // CHECK-LABEL: @_Z3fooR9ad_struct // CHECK: [[PTRINT1:%.+]] = ptrtoint // CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], 63 // CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 // CHECK: call void @llvm.assume(i1 [[MASKCOND1]]) return x.a; } double *goo(ad_struct *x) { // CHECK-LABEL: @_Z3gooP9ad_struct // CHECK: [[PTRINT2:%.+]] = ptrtoint // CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], 63 // CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0 // CHECK: call void @llvm.assume(i1 [[MASKCOND2]]) return x->a; }
// _ReadIndex void ResourceFile::_ReadIndex() { // read the header resource_index_section_header header; read_exactly(fFile, kResourceIndexSectionOffset, &header, kResourceIndexSectionHeaderSize, "Failed to read the resource index section header."); // check the header // index section offset uint32 indexSectionOffset = _GetUInt32(header.rish_index_section_offset); if (indexSectionOffset != kResourceIndexSectionOffset) { throw Exception("Unexpected resource index section offset. Is: %lu, " "should be: %lu.", indexSectionOffset, kResourceIndexSectionOffset); } // index section size uint32 expectedIndexSectionSize = kResourceIndexSectionHeaderSize + kResourceIndexEntrySize * fResourceCount; expectedIndexSectionSize = align_value(expectedIndexSectionSize, kResourceIndexSectionAlignment); uint32 indexSectionSize = _GetUInt32(header.rish_index_section_size); if (indexSectionSize != expectedIndexSectionSize) { throw Exception("Unexpected resource index section size. Is: %lu, " "should be: %lu.", indexSectionSize, expectedIndexSectionSize); } // unknown section offset uint32 unknownSectionOffset = _GetUInt32(header.rish_unknown_section_offset); if (unknownSectionOffset != indexSectionOffset + indexSectionSize) { throw Exception("Unexpected resource index section size. Is: %lu, " "should be: %lu.", unknownSectionOffset, indexSectionOffset + indexSectionSize); } // unknown section size uint32 unknownSectionSize = _GetUInt32(header.rish_unknown_section_size); if (unknownSectionSize != kUnknownResourceSectionSize) { throw Exception("Unexpected resource index section offset. Is: %lu, " "should be: %lu.", unknownSectionOffset, kUnknownResourceSectionSize); } // info table offset and size uint32 infoTableOffset = _GetUInt32(header.rish_info_table_offset); uint32 infoTableSize = _GetUInt32(header.rish_info_table_size); if (infoTableOffset + infoTableSize > fFileSize) throw Exception("Invalid info table location."); fInfoTableItem = new ResourceItem; fInfoTableItem->SetLocation(infoTableOffset, infoTableSize); // read the index entries uint32 indexTableOffset = indexSectionOffset + kResourceIndexSectionHeaderSize; int32 maxResourceCount = (unknownSectionOffset - indexTableOffset) / kResourceIndexEntrySize; int32 actualResourceCount = 0; bool tableEndReached = false; for (int32 i = 0; !tableEndReached && i < maxResourceCount; i++) { // read one entry tableEndReached = !_ReadIndexEntry(i, indexTableOffset, (i >= fResourceCount)); if (!tableEndReached) actualResourceCount++; } // check resource count if (actualResourceCount != fResourceCount) { if (actualResourceCount > fResourceCount) { Warnings::AddCurrentWarning("Resource index table contains " "%ld entries, although it should be " "%ld only.", actualResourceCount, fResourceCount); } fResourceCount = actualResourceCount; } }
// _InitELFFile void ResourceFile::_InitELFFile(BFile& file) { status_t error = B_OK; // get the file size off_t fileSize = 0; error = file.GetSize(&fileSize); if (error != B_OK) throw Exception(error, "Failed to get the file size."); // read ELF header Elf32_Ehdr fileHeader; read_exactly(file, 0, &fileHeader, sizeof(Elf32_Ehdr), "Failed to read ELF header."); // check data encoding (endianess) switch (fileHeader.e_ident[EI_DATA]) { case ELFDATA2LSB: fHostEndianess = B_HOST_IS_LENDIAN; break; case ELFDATA2MSB: fHostEndianess = B_HOST_IS_BENDIAN; break; default: case ELFDATANONE: throw Exception("Unsupported ELF data encoding."); break; } // get the header values uint32 headerSize = _GetUInt16(fileHeader.e_ehsize); uint32 programHeaderTableOffset = _GetUInt32(fileHeader.e_phoff); uint32 programHeaderSize = _GetUInt16(fileHeader.e_phentsize); uint32 programHeaderCount = _GetUInt16(fileHeader.e_phnum); uint32 sectionHeaderTableOffset = _GetUInt32(fileHeader.e_shoff); uint32 sectionHeaderSize = _GetUInt16(fileHeader.e_shentsize); uint32 sectionHeaderCount = _GetUInt16(fileHeader.e_shnum); bool hasProgramHeaderTable = (programHeaderTableOffset != 0); bool hasSectionHeaderTable = (sectionHeaderTableOffset != 0); //printf("headerSize : %lu\n", headerSize); //printf("programHeaderTableOffset: %lu\n", programHeaderTableOffset); //printf("programHeaderSize : %lu\n", programHeaderSize); //printf("programHeaderCount : %lu\n", programHeaderCount); //printf("sectionHeaderTableOffset: %lu\n", sectionHeaderTableOffset); //printf("sectionHeaderSize : %lu\n", sectionHeaderSize); //printf("sectionHeaderCount : %lu\n", sectionHeaderCount); // check the sanity of the header values // ELF header size if (headerSize < sizeof(Elf32_Ehdr) || headerSize > kMaxELFHeaderSize) { throw Exception("Invalid ELF header: invalid ELF header size: %lu.", headerSize); } uint32 resourceOffset = headerSize; uint32 resourceAlignment = 0; // program header table offset and entry count/size uint32 programHeaderTableSize = 0; if (hasProgramHeaderTable) { if (programHeaderTableOffset < headerSize || programHeaderTableOffset > fileSize) { throw Exception("Invalid ELF header: invalid program header table " "offset: %lu.", programHeaderTableOffset); } programHeaderTableSize = programHeaderSize * programHeaderCount; if (programHeaderSize < sizeof(Elf32_Phdr) || programHeaderTableOffset + programHeaderTableSize > fileSize) { throw Exception("Invalid ELF header: program header table exceeds " "file: %lu.", programHeaderTableOffset + programHeaderTableSize); } resourceOffset = max(resourceOffset, programHeaderTableOffset + programHeaderTableSize); // iterate through the program headers for (int32 i = 0; i < (int32)programHeaderCount; i++) { uint32 shOffset = programHeaderTableOffset + i * programHeaderSize; Elf32_Phdr programHeader; read_exactly(file, shOffset, &programHeader, sizeof(Elf32_Shdr), "Failed to read ELF program header."); // get the header values uint32 type = _GetUInt32(programHeader.p_type); uint32 offset = _GetUInt32(programHeader.p_offset); uint32 size = _GetUInt32(programHeader.p_filesz); uint32 alignment = _GetUInt32(programHeader.p_align); //printf("segment: type: %ld, offset: %lu, size: %lu, alignment: %lu\n", //type, offset, size, alignment); // check the values // PT_NULL marks the header unused, if (type != PT_NULL) { if (/*offset < headerSize ||*/ offset > fileSize) { throw Exception("Invalid ELF program header: invalid " "program offset: %lu.", offset); } uint32 segmentEnd = offset + size; if (segmentEnd > fileSize) { throw Exception("Invalid ELF section header: segment " "exceeds file: %lu.", segmentEnd); } resourceOffset = max(resourceOffset, segmentEnd); resourceAlignment = max(resourceAlignment, alignment); } } } // section header table offset and entry count/size uint32 sectionHeaderTableSize = 0; if (hasSectionHeaderTable) { if (sectionHeaderTableOffset < headerSize || sectionHeaderTableOffset > fileSize) { throw Exception("Invalid ELF header: invalid section header table " "offset: %lu.", sectionHeaderTableOffset); } sectionHeaderTableSize = sectionHeaderSize * sectionHeaderCount; if (sectionHeaderSize < sizeof(Elf32_Shdr) || sectionHeaderTableOffset + sectionHeaderTableSize > fileSize) { throw Exception("Invalid ELF header: section header table exceeds " "file: %lu.", sectionHeaderTableOffset + sectionHeaderTableSize); } resourceOffset = max(resourceOffset, sectionHeaderTableOffset + sectionHeaderTableSize); // iterate through the section headers for (int32 i = 0; i < (int32)sectionHeaderCount; i++) { uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize; Elf32_Shdr sectionHeader; read_exactly(file, shOffset, §ionHeader, sizeof(Elf32_Shdr), "Failed to read ELF section header."); // get the header values uint32 type = _GetUInt32(sectionHeader.sh_type); uint32 offset = _GetUInt32(sectionHeader.sh_offset); uint32 size = _GetUInt32(sectionHeader.sh_size); //printf("section: type: %ld, offset: %lu, size: %lu\n", type, offset, size); // check the values // SHT_NULL marks the header unused, // SHT_NOBITS sections take no space in the file if (type != SHT_NULL && type != SHT_NOBITS) { if (offset < headerSize || offset > fileSize) { throw Exception("Invalid ELF section header: invalid " "section offset: %lu.", offset); } uint32 sectionEnd = offset + size; if (sectionEnd > fileSize) { throw Exception("Invalid ELF section header: section " "exceeds file: %lu.", sectionEnd); } resourceOffset = max(resourceOffset, sectionEnd); } } } //printf("resourceOffset: %lu\n", resourceOffset); // align the offset if (resourceAlignment < kELFMinResourceAlignment) resourceAlignment = kELFMinResourceAlignment; if (resourceAlignment > kELFMaxResourceAlignment) { throw Exception("The ELF object file requires an invalid alignment: " "%lu.", resourceAlignment); } resourceOffset = align_value(resourceOffset, resourceAlignment); //printf("resourceOffset: %lu\n", resourceOffset); if (resourceOffset >= fileSize) throw Exception("The ELF object file does not contain resources."); // fine, init the offset file fFile.SetTo(file, resourceOffset); }
// WriteResources uint32 ResourceFile::WriteResources(void* buffer, uint32 bufferSize) { // calculate sizes and offsets // header uint32 size = kResourcesHeaderSize; // index section uint32 indexSectionOffset = size; uint32 indexSectionSize = kResourceIndexSectionHeaderSize + fResourceCount * kResourceIndexEntrySize; indexSectionSize = align_value(indexSectionSize, kResourceIndexSectionAlignment); size += indexSectionSize; // unknown section uint32 unknownSectionOffset = size; uint32 unknownSectionSize = kUnknownResourceSectionSize; size += unknownSectionSize; // data uint32 dataOffset = size; uint32 dataSize = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); dataSize += item->GetSize(); } size += dataSize; // info table uint32 infoTableOffset = size; uint32 infoTableSize = 0; type_code type = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); if (i == 0 || type != item->GetType()) { if (i != 0) infoTableSize += kResourceInfoSeparatorSize; type = item->GetType(); infoTableSize += kMinResourceInfoBlockSize; } else infoTableSize += kMinResourceInfoSize; uint32 nameLen = strlen(item->GetName()); if (nameLen != 0) infoTableSize += nameLen + 1; } infoTableSize += kResourceInfoSeparatorSize + kResourceInfoTableEndSize; size += infoTableSize; // check whether the buffer is large enough if (!buffer) throw Exception("Supplied buffer is NULL."); if (bufferSize < size) throw Exception("Supplied buffer is too small."); // write... void* data = buffer; // header resources_header* resourcesHeader = (resources_header*)data; resourcesHeader->rh_resources_magic = kResourcesHeaderMagic; resourcesHeader->rh_resource_count = fResourceCount; resourcesHeader->rh_index_section_offset = indexSectionOffset; resourcesHeader->rh_admin_section_size = indexSectionOffset + indexSectionSize; for (int32 i = 0; i < 13; i++) resourcesHeader->rh_pad[i] = 0; // index section // header data = skip_bytes(buffer, indexSectionOffset); resource_index_section_header* indexHeader = (resource_index_section_header*)data; indexHeader->rish_index_section_offset = indexSectionOffset; indexHeader->rish_index_section_size = indexSectionSize; indexHeader->rish_unknown_section_offset = unknownSectionOffset; indexHeader->rish_unknown_section_size = unknownSectionSize; indexHeader->rish_info_table_offset = infoTableOffset; indexHeader->rish_info_table_size = infoTableSize; fill_pattern(buffer, &indexHeader->rish_unused_data1, 1); fill_pattern(buffer, indexHeader->rish_unused_data2, 25); fill_pattern(buffer, &indexHeader->rish_unused_data3, 1); // index table data = skip_bytes(data, kResourceIndexSectionHeaderSize); resource_index_entry* entry = (resource_index_entry*)data; uint32 entryOffset = dataOffset; for (int32 i = 0; i < fResourceCount; i++, entry++) { ResourceItem* item = ItemAt(i); uint32 entrySize = item->GetSize(); entry->rie_offset = entryOffset; entry->rie_size = entrySize; entry->rie_pad = 0; entryOffset += entrySize; } // padding + unknown section data = skip_bytes(buffer, dataOffset); fill_pattern(buffer, entry, data); // data for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); status_t error = item->LoadData(fFile); if (error != B_OK) throw Exception(error, "Error loading resource data."); uint32 entrySize = item->GetSize(); memcpy(data, item->GetData(), entrySize); data = skip_bytes(data, entrySize); } // info table data = skip_bytes(buffer, infoTableOffset); type = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); resource_info* info = NULL; if (i == 0 || type != item->GetType()) { if (i != 0) { resource_info_separator* separator = (resource_info_separator*)data; separator->ris_value1 = 0xffffffff; separator->ris_value2 = 0xffffffff; data = skip_bytes(data, kResourceInfoSeparatorSize); } type = item->GetType(); resource_info_block* infoBlock = (resource_info_block*)data; infoBlock->rib_type = type; info = infoBlock->rib_info; } else info = (resource_info*)data; // info info->ri_id = item->GetID(); info->ri_index = i + 1; info->ri_name_size = 0; data = info->ri_name; uint32 nameLen = strlen(item->GetName()); if (nameLen != 0) { memcpy(info->ri_name, item->GetName(), nameLen + 1); data = skip_bytes(data, nameLen + 1); info->ri_name_size = nameLen + 1; } } // separator resource_info_separator* separator = (resource_info_separator*)data; separator->ris_value1 = 0xffffffff; separator->ris_value2 = 0xffffffff; // table end data = skip_bytes(data, kResourceInfoSeparatorSize); resource_info_table_end* tableEnd = (resource_info_table_end*)data; void* infoTable = skip_bytes(buffer, infoTableOffset); tableEnd->rite_check_sum = calculate_checksum(infoTable, infoTableSize - kResourceInfoTableEndSize); tableEnd->rite_terminator = 0; // final check data = skip_bytes(data, kResourceInfoTableEndSize); uint32 bytesWritten = (char*)data - (char*)buffer; if (bytesWritten != size) { throw Exception("Bad boy error: Wrote %lu bytes, though supposed to " "write %lu bytes.", bytesWritten, size); } return size; }
int main(int argc, char *argv[]) { FILE *fout, *fasm, *fhdr = NULL, *frlist; const struct parsed_proto *pp; int no_decorations = 0; char comment_char = '#'; char words[20][256]; char word[256]; char line[256]; char last_sym[32]; unsigned long val; unsigned long cnt; const char *sym; enum dx_type type; char **pub_syms; int pub_sym_cnt = 0; int pub_sym_alloc; char **rlist; int rlist_cnt = 0; int rlist_alloc; int header_mode = 0; int is_ro = 0; int is_label; int is_bss; int wordc; int first; int arg_out; int arg = 1; int len; int w, i; char *p; char *p2; if (argc < 4) { // -nd: no symbol decorations printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> <hdrf> [rlist]*\n" "%s -hdr <.h> <.asm>\n", argv[0], argv[0]); return 1; } for (arg = 1; arg < argc; arg++) { if (IS(argv[arg], "-nd")) no_decorations = 1; else if (IS(argv[arg], "-i")) g_cconv_novalidate = 1; else if (IS(argv[arg], "-a")) { comment_char = '@'; g_arm_mode = 1; } else if (IS(argv[arg], "-hdr")) header_mode = 1; else break; } arg_out = arg++; asmfn = argv[arg++]; fasm = fopen(asmfn, "r"); my_assert_not(fasm, NULL); if (!header_mode) { hdrfn = argv[arg++]; fhdr = fopen(hdrfn, "r"); my_assert_not(fhdr, NULL); } fout = fopen(argv[arg_out], "w"); my_assert_not(fout, NULL); pub_sym_alloc = 64; pub_syms = malloc(pub_sym_alloc * sizeof(pub_syms[0])); my_assert_not(pub_syms, NULL); rlist_alloc = 64; rlist = malloc(rlist_alloc * sizeof(rlist[0])); my_assert_not(rlist, NULL); for (; arg < argc; arg++) { frlist = fopen(argv[arg], "r"); my_assert_not(frlist, NULL); while (my_fgets(line, sizeof(line), frlist)) { p = sskip(line); if (*p == 0 || *p == ';') continue; p = next_word(words[0], sizeof(words[0]), p); if (words[0][0] == 0) continue; if (rlist_cnt >= rlist_alloc) { rlist_alloc = rlist_alloc * 2 + 64; rlist = realloc(rlist, rlist_alloc * sizeof(rlist[0])); my_assert_not(rlist, NULL); } rlist[rlist_cnt++] = strdup(words[0]); } fclose(frlist); frlist = NULL; } if (rlist_cnt > 0) qsort(rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp); qsort(unwanted_syms, ARRAY_SIZE(unwanted_syms), sizeof(unwanted_syms[0]), cmpstringp); last_sym[0] = 0; while (1) { next_section(fasm, line); if (feof(fasm)) break; if (IS(line + 1, "text")) continue; if (IS(line + 1, "rdata")) { is_ro = 1; if (!header_mode) fprintf(fout, "\n.section .rodata\n"); } else if (IS(line + 1, "data")) { is_ro = 0; if (!header_mode) fprintf(fout, "\n.data\n"); } else aerr("unhandled section: '%s'\n", line); if (!header_mode) fprintf(fout, ".align %d\n", align_value(4)); while (my_fgets(line, sizeof(line), fasm)) { sym = NULL; asmln++; p = sskip(line); if (*p == 0) continue; if (*p == ';') { if (IS_START(p, ";org") && sscanf(p + 5, "%Xh", &i) == 1) { // ;org is only seen at section start, so assume . addr 0 i &= 0xfff; if (i != 0 && !header_mode) fprintf(fout, "\t\t .skip 0x%x\n", i); } continue; } for (wordc = 0; wordc < ARRAY_SIZE(words); wordc++) { p = sskip(next_word_s(words[wordc], sizeof(words[0]), p)); if (*p == 0 || *p == ';') { wordc++; break; } if (*p == ',') { p = sskip(p + 1); } } if (*p == ';') { p = sskip(p + 1); if (IS_START(p, "sctclrtype")) g_func_sym_pp = NULL; } if (wordc == 2 && IS(words[1], "ends")) break; if (wordc <= 2 && IS(words[0], "end")) break; if (wordc < 2) aerr("unhandled: '%s'\n", words[0]); // don't cares if (IS(words[0], "assume")) continue; if (IS(words[0], "align")) { if (header_mode) continue; val = parse_number(words[1]); fprintf(fout, "\t\t .align %d", align_value(val)); goto fin; } w = 1; type = parse_dx_directive(words[0]); if (type == DXT_UNSPEC) { type = parse_dx_directive(words[1]); sym = words[0]; w = 2; } if (type == DXT_UNSPEC) aerr("unhandled decl: '%s %s'\n", words[0], words[1]); if (sym != NULL) { if (header_mode) { int is_str = 0; fprintf(fout, "extern "); if (is_ro) fprintf(fout, "const "); switch (type) { case DXT_BYTE: for (i = w; i < wordc; i++) if (words[i][0] == '\'') is_str = 1; if (is_str) fprintf(fout, "char %s[];\n", sym); else fprintf(fout, "uint8_t %s;\n", sym); break; case DXT_WORD: fprintf(fout, "uint16_t %s;\n", sym); break; case DXT_DWORD: fprintf(fout, "uint32_t %s;\n", sym); break; default: fprintf(fout, "_UNKNOWN %s;\n", sym); break; } continue; } snprintf(last_sym, sizeof(last_sym), "%s", sym); pp = proto_parse(fhdr, sym, 1); if (pp != NULL) { g_func_sym_pp = NULL; // public/global name if (pub_sym_cnt >= pub_sym_alloc) { pub_sym_alloc *= 2; pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0])); my_assert_not(pub_syms, NULL); } pub_syms[pub_sym_cnt++] = strdup(sym); } len = strlen(sym); fprintf(fout, "%s%s:", no_decorations ? "" : "_", sym); len += 2; if (len < 8) fprintf(fout, "\t"); if (len < 16) fprintf(fout, "\t"); if (len <= 16) fprintf(fout, " "); else fprintf(fout, " "); } else { if (header_mode) continue; fprintf(fout, "\t\t "); } // fill out some unwanted strings with zeroes.. if (type == DXT_BYTE && words[w][0] == '\'' && is_unwanted_sym(last_sym)) { len = 0; for (; w < wordc; w++) { if (words[w][0] == '\'') { p = words[w] + 1; for (; *p && *p != '\''; p++) len++; } else { // assume encoded byte len++; } } fprintf(fout, ".skip %d", len); goto fin; } else if (type == DXT_BYTE && (words[w][0] == '\'' || (w + 1 < wordc && words[w + 1][0] == '\''))) { // string; use asciz for most common case if (w == wordc - 2 && IS(words[w + 1], "0")) { fprintf(fout, ".asciz \""); wordc--; } else fprintf(fout, ".ascii \""); for (; w < wordc; w++) { if (words[w][0] == '\'') { p = words[w] + 1; p2 = strchr(p, '\''); if (p2 == NULL) aerr("unterminated string? '%s'\n", p); memcpy(word, p, p2 - p); word[p2 - p] = 0; fprintf(fout, "%s", escape_string(word)); } else { val = parse_number(words[w]); if (val & ~0xff) aerr("bad string trailing byte?\n"); // unfortunately \xHH is unusable - gas interprets // things like \x27b as 0x7b, so have to use octal here fprintf(fout, "\\%03lo", val); } } fprintf(fout, "\""); goto fin; } if (w == wordc - 2) { if (IS_START(words[w + 1], "dup(")) { cnt = parse_number(words[w]); p = words[w + 1] + 4; p2 = strchr(p, ')'); if (p2 == NULL) aerr("bad dup?\n"); memmove(word, p, p2 - p); word[p2 - p] = 0; val = 0; if (!IS(word, "?")) val = parse_number(word); fprintf(fout, ".fill 0x%02lx,%d,0x%02lx", cnt, type_size(type), val); goto fin; } } if (type == DXT_DWORD && words[w][0] == '\'' && words[w][5] == '\'' && strlen(words[w]) == 6) { if (w != wordc - 1) aerr("TODO\n"); p = words[w]; val = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]; fprintf(fout, ".long 0x%lx", val); snprintf(g_comment, sizeof(g_comment), "%s", words[w]); goto fin; } if (type >= DXT_DWORD && strchr(words[w], '.')) { if (w != wordc - 1) aerr("TODO\n"); if (g_arm_mode && type == DXT_TEN) { fprintf(fout, ".fill 10"); snprintf(g_comment, sizeof(g_comment), "%s %s", type_name_float(type), words[w]); } else fprintf(fout, "%s %s", type_name_float(type), words[w]); goto fin; } first = 1; fprintf(fout, "%s ", type_name(type)); for (; w < wordc; w++) { if (!first) fprintf(fout, ", "); is_label = is_bss = 0; if (w <= wordc - 2 && IS(words[w], "offset")) { is_label = 1; w++; } else if (IS(words[w], "?")) { is_bss = 1; } else if (type == DXT_DWORD && !('0' <= words[w][0] && words[w][0] <= '9')) { // assume label is_label = 1; } if (is_bss) { fprintf(fout, "0"); } else if (is_label) { p = words[w]; if (IS_START(p, "loc_") || IS_START(p, "__imp") || strchr(p, '?') || strchr(p, '@') || bsearch(&p, rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp)) { fprintf(fout, "0"); snprintf(g_comment, sizeof(g_comment), "%s", p); } else { pp = check_var(fhdr, sym, p); if (pp == NULL) { fprintf(fout, "%s%s", (no_decorations || p[0] == '_') ? "" : "_", p); } else { if (no_decorations) fprintf(fout, "%s", pp->name); else output_decorated_pp(fout, pp); } } } else { val = parse_number(words[w]); if (val < 10) fprintf(fout, "%ld", val); else fprintf(fout, "0x%lx", val); } first = 0; } fin: if (g_comment[0] != 0) { fprintf(fout, "\t\t%c %s", comment_char, g_comment); g_comment[0] = 0; } fprintf(fout, "\n"); } } fprintf(fout, "\n"); // dump public syms for (i = 0; i < pub_sym_cnt; i++) fprintf(fout, ".global %s%s\n", no_decorations ? "" : "_", pub_syms[i]); fclose(fout); fclose(fasm); if (fhdr != NULL) fclose(fhdr); return 0; }
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE // RUN: %clang_cc1 -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE typedef char **__attribute__((align_value(0x80000000))) aligned_char; struct ac_struct { // CHECK: %[[STRUCT_AC_STRUCT:.*]] = type { i8** } aligned_char a; }; // CHECK-SANITIZE-ANYRECOVER: @[[ALIGNED_CHAR:.*]] = {{.*}} c"'aligned_char' (aka 'char **')\00" } // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 13 }, {{.*}}* @[[ALIGNED_CHAR]] } char **load_from_ac_struct(struct ac_struct *x) { // CHECK: define i8** @{{.*}}(%[[STRUCT_AC_STRUCT]]* %[[X:.*]]) // CHECK-NEXT: [[ENTRY:.*]]: // CHECK-NEXT: %[[STRUCT_AC_STRUCT_ADDR:.*]] = alloca %[[STRUCT_AC_STRUCT]]*, align 8 // CHECK-NEXT: store %[[STRUCT_AC_STRUCT]]* %[[X]], %[[STRUCT_AC_STRUCT]]** %[[STRUCT_AC_STRUCT_ADDR]], align 8 // CHECK-NEXT: %[[X_RELOADED:.*]] = load %[[STRUCT_AC_STRUCT]]*, %[[STRUCT_AC_STRUCT]]** %[[STRUCT_AC_STRUCT_ADDR]], align 8 // CHECK: %[[A_ADDR:.*]] = getelementptr inbounds %[[STRUCT_AC_STRUCT]], %[[STRUCT_AC_STRUCT]]* %[[X_RELOADED]], i32 0, i32 0 // CHECK: %[[A:.*]] = load i8**, i8*** %[[A_ADDR]], align 8 // CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[A]] to i64 // CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647 // CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0 // CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[A]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize