CACHE_BASE::CACHE_BASE(std::string name, UINT32 cacheSize, UINT32 lineSize, UINT32 associativity) : _name(name), _cacheSize(cacheSize), _lineSize(lineSize), _associativity(associativity), _lineShift(FloorLog2(lineSize)), _setIndexMask((cacheSize / (associativity * lineSize)) - 1) { ASSERTX(IsPower2(_lineSize)); ASSERTX(IsPower2(_setIndexMask + 1)); for (UINT32 accessType = 0; accessType < ACCESS_TYPE_NUM; accessType++) { _access[accessType][false] = 0; _access[accessType][true] = 0; } }
void CELF2ASM<ELFSTRUCTURES>::MakeSectionList() { // Make Sections list and Relocations list in Disasm // Allocate array for translating oroginal section numbers to new index SectionNumberTranslate.SetNum(this->NSections + 1); uint32 NewSectionIndex = 0; for (uint32 sc = 0; sc < this->NSections; sc++) { // Get copy of 32-bit header or converted 64-bit header TELF_SectionHeader sheader = this->SectionHeaders[sc]; int entrysize = (uint32)(sheader.sh_entsize); uint32 namei = sheader.sh_name; if (namei >= this->SecStringTableLen) { err.submit(2112); break; } // if (sheader.sh_type == SHT_PROGBITS || sheader.sh_type == SHT_NOBITS) { // // This is a code, data or bss section if (sheader.sh_flags & SHF_ALLOC) { // This is an allocated section // Give it a new index SectionNumberTranslate[sc] = ++NewSectionIndex; // Get section parameters uint8 * Buffer = (uint8*)(this->Buf()) + (uint32)sheader.sh_offset; uint32 InitSize = (sheader.sh_type == SHT_NOBITS) ? 0 : (uint32)sheader.sh_size; uint32 TotalSize = (uint32)sheader.sh_size; uint32 SectionAddress = (uint32)sheader.sh_addr - (uint32)ImageBase; uint32 Align = FloorLog2((uint32)sheader.sh_addralign); const char * Name = this->SecStringTable + namei; // Detect segment type uint32 Type = 0; if (sheader.sh_flags & SHF_ALLOC) { // Allocate if (sheader.sh_type == SHT_NOBITS) { // Uninitialized data Type = 3; } else if (sheader.sh_flags & SHF_EXECINSTR) { // Executable Type = 1; } else if (!(sheader.sh_flags & SHF_WRITE)) { // Not writeable Type = 4; } else { // Initialized writeable data Type = 2; } } // Save section record Disasm.AddSection(Buffer, InitSize, TotalSize, SectionAddress, Type, Align, this->WordSize, Name); } } }
GLXPixmap GLXLibrary::CreatePixmap(gfxASurface* aSurface) { if (!SupportsTextureFromPixmap(aSurface)) { return None; } gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface); const XRenderPictFormat *format = xs->XRenderFormat(); if (!format || format->type != PictTypeDirect) { return None; } const XRenderDirectFormat& direct = format->direct; int alphaSize = FloorLog2(direct.alphaMask + 1); NS_ASSERTION((1 << alphaSize) - 1 == direct.alphaMask, "Unexpected render format with non-adjacent alpha bits"); int attribs[] = { LOCAL_GLX_DOUBLEBUFFER, False, LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT, LOCAL_GLX_ALPHA_SIZE, alphaSize, (alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT : LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True, LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT, None }; int numConfigs = 0; Display *display = xs->XDisplay(); int xscreen = DefaultScreen(display); ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display, xscreen, attribs, &numConfigs)); // Find an fbconfig that matches the pixel format used on the Pixmap. int matchIndex = -1; unsigned long redMask = static_cast<unsigned long>(direct.redMask) << direct.red; unsigned long greenMask = static_cast<unsigned long>(direct.greenMask) << direct.green; unsigned long blueMask = static_cast<unsigned long>(direct.blueMask) << direct.blue; // This is true if the Pixmap has bits for alpha or unused bits. bool haveNonColorBits = ~(redMask | greenMask | blueMask) != -1UL << format->depth; for (int i = 0; i < numConfigs; i++) { int id = None; sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id); Visual *visual; int depth; FindVisualAndDepth(display, id, &visual, &depth); if (!visual || visual->c_class != TrueColor || visual->red_mask != redMask || visual->green_mask != greenMask || visual->blue_mask != blueMask ) { continue; } // Historically Xlib Visuals did not try to represent an alpha channel // and there was no means to use an alpha channel on a Pixmap. The // Xlib Visual from the fbconfig was not intended to have any // information about alpha bits. // // Since then, RENDER has added formats for 32 bit depth Pixmaps. // Some of these formats have bits for alpha and some have unused // bits. // // Then the Composite extension added a 32 bit depth Visual intended // for Windows with an alpha channel, so bits not in the visual color // masks were expected to be treated as alpha bits. // // Usually GLX counts only color bits in the Visual depth, but the // depth of Composite's ARGB Visual includes alpha bits. However, // bits not in the color masks are not necessarily alpha bits because // sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32 // bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA // again). // // This checks that the depth matches in one of the two ways. // NVIDIA now forces format->depth == depth so only the first way // is checked for NVIDIA if (depth != format->depth && (mIsNVIDIA || depth != format->depth - alphaSize) ) { continue; } // If all bits of the Pixmap are color bits and the Pixmap depth // matches the depth of the fbconfig visual, then we can assume that // the driver will do whatever is necessary to ensure that any // GLXPixmap alpha bits are treated as set. We can skip the // ALPHA_SIZE check in this situation. We need to skip this check for // situations (ATI) where there are no fbconfigs without alpha bits. // // glXChooseFBConfig should prefer configs with smaller // LOCAL_GLX_BUFFER_SIZE, so we should still get zero alpha bits if // available, except perhaps with NVIDIA drivers where buffer size is // not the specified sum of the component sizes. if (haveNonColorBits) { // There are bits in the Pixmap format that haven't been matched // against the fbconfig visual. These bits could either represent // alpha or be unused, so just check that the number of alpha bits // matches. int size = 0; sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_ALPHA_SIZE, &size); if (size != alphaSize) { continue; } } matchIndex = i; break; } if (matchIndex == -1) { // GLX can't handle A8 surfaces, so this is not really unexpected. The // caller should deal with this situation. NS_WARN_IF_FALSE(format->depth == 8, "[GLX] Couldn't find a FBConfig matching Pixmap format"); return None; } int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT, LOCAL_GLX_TEXTURE_FORMAT_EXT, (alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT : LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT), None}; GLXPixmap glxpixmap = xCreatePixmap(display, cfgs[matchIndex], xs->XDrawable(), pixmapAttribs); return glxpixmap; }
void CELF2MAC<ELFSTRUCTURES,MACSTRUCTURES>::MakeSections() { // Convert subfunction: Make sections and relocation tables uint32 oldsec; // Section number in old file uint32 relsec; // Relocation section in old file TMAC_section NewHeader; // New section header TELF_SectionHeader OldHeader; // Old section header TELF_SectionHeader OldRelHeader;// Old relocation section header uint32 NewVirtualAddress = 0; // Virtual address of new section uint32 NewRawDataOffset = 0; // Offset into NewRawData of section. // NewRawDataOffset is different from NewVirtualAddress if alignment of sections in // the object file is different from alignment of sections in memory // Count cumulative number of symbols in each scope NumSymbols[0] = 0; NumSymbols[1] = NumSymbols[0] + NewSymTab[0].GetNumEntries(); NumSymbols[2] = NumSymbols[1] + NewSymTab[1].GetNumEntries(); NumSymbols[3] = NumSymbols[2] + NewSymTab[2].GetNumEntries(); if (NumSymbols[3] >= 0x1000000) err.submit(2051); // Too many symbols, max = 2^24 NewSectHeadOffset = ToFile.GetDataSize(); // Second loop through old sections for (oldsec = 0; oldsec < this->NSections; oldsec++) { // Copy old header for convenience OldHeader = this->SectionHeaders[oldsec]; if (OldHeader.sh_size == 0) { // Remove empty section // The linker has a bug with empty sections continue; } // Search for program data sections only if (OldHeader.sh_type == SHT_PROGBITS || OldHeader.sh_type == SHT_NOBITS) { // Reset new section header memset(&NewHeader, 0, sizeof(NewHeader)); // Section name const char * sname = ""; uint32 namei = OldHeader.sh_name; if (namei >= this->SecStringTableLen) err.submit(2112); else sname = this->SecStringTable + namei; // Translate section name and truncate to 16 characters if (!stricmp(sname,".text") || !stricmp(sname,"_text")) { strcpy(NewHeader.sectname, "__text"); strcpy(NewHeader.segname, "__TEXT"); } else if (!stricmp(sname,".data") || !stricmp(sname,"_data")) { strcpy(NewHeader.sectname, "__data"); strcpy(NewHeader.segname, "__DATA"); } else if (!strnicmp(sname+1,"bss", 3)) { strcpy(NewHeader.sectname, "__bss"); strcpy(NewHeader.segname, "__DATA"); } else if (!strnicmp(sname+1,"const", 5) || !strnicmp(sname+1,"rodata", 6)) { strcpy(NewHeader.sectname, "__const"); strcpy(NewHeader.segname, "__DATA"); } else if (!strnicmp(sname, ELF_CONSTRUCTOR_NAME, 5)) { // Constructors strcpy(NewHeader.sectname, MAC_CONSTRUCTOR_NAME); strcpy(NewHeader.segname, "__DATA"); NewHeader.flags = MAC_S_MOD_INIT_FUNC_POINTERS; } else if (OldHeader.sh_flags & SHF_EXECINSTR) { // Other code section if (strlen(NewHeader.sectname) > 16) err.submit(1040, NewHeader.sectname); // Warning: name truncated strncpy(NewHeader.sectname, sname, 16); strcpy(NewHeader.segname, "__TEXT"); } else { // Other data section. Truncate name to 16 characters if (strlen(NewHeader.sectname) > 16) err.submit(1040, NewHeader.sectname); // Warning: name truncated strncpy(NewHeader.sectname, sname, 16); strcpy(NewHeader.segname, "__DATA"); } if (NewHeader.sectname[0] == '.') { // Make sure name begins with '_' NewHeader.sectname[0] = '_'; } // Raw data NewHeader.size = OldHeader.sh_size; // section size in file // File to raw data for section NewHeader.offset = NewRawData.GetDataSize() + RawDataOffset; if (OldHeader.sh_size && OldHeader.sh_type != SHT_NOBITS) { // Not for .bss segment // Copy raw data NewRawDataOffset = NewRawData.Push(this->Buf()+(uint32)OldHeader.sh_offset, (uint32)OldHeader.sh_size); NewRawData.Align(4); } // Section flags if (OldHeader.sh_flags & SHF_EXECINSTR) { NewHeader.flags |= MAC_S_ATTR_PURE_INSTRUCTIONS | MAC_S_ATTR_SOME_INSTRUCTIONS; } else if (OldHeader.sh_type == SHT_NOBITS) { NewHeader.flags |= MAC_S_ZEROFILL; // .bss segment } // Alignment NewHeader.align = FloorLog2((uint32)OldHeader.sh_addralign); if (NewHeader.align > 12) NewHeader.align = 12; // What is the limit for highest alignment? int AlignBy = 1 << NewHeader.align; // Align memory address NewVirtualAddress = (NewVirtualAddress + AlignBy - 1) & -AlignBy; // Virtual memory address of new section NewHeader.addr = NewVirtualAddress; NewVirtualAddress += (uint32)OldHeader.sh_size; // Find relocation table for this section by searching through all sections for (relsec = 1; relsec < this->NSections; relsec++) { // Get section header OldRelHeader = this->SectionHeaders[relsec]; // Check if this is a relocations section referring to oldsec if ((OldRelHeader.sh_type == SHT_REL || OldRelHeader.sh_type == SHT_RELA) // if section is relocation && OldRelHeader.sh_info == oldsec) { // and if section refers to current section Elf2MacRelocations(OldRelHeader, NewHeader, NewRawDataOffset, oldsec); } } // End of search for relocation table // Align raw data for next section NewRawData.Align(4); // Fix v. 2.14: adjust NewVirtualAddress to match above alignment NewVirtualAddress = (NewVirtualAddress + 3) & MInt(-4); // Store section header in file ToFile.Push(&NewHeader, sizeof(NewHeader)); } // End of if section has program data } // End of loop through old sections } // End of function MakeSections
void CELF2MAC<ELFSTRUCTURES,MACSTRUCTURES>::MakeSectionsIndex() { // Make sections index translation table and section offset table. // We must make these tables before the sections, because they are needed for the // symbol tables and relocation tables, and we must make the symbol tables before // the relocation tables, and we must make the relocation tables together with the // sections. uint32 oldsec; // Section number in old file uint32 newsec = 0; // Section number in new file NewSectIndex. SetNum(this->NSections); // Allocate size for section index table NewSectIndex. SetZero(); // Initialize NewSectOffset.SetNum(this->NSections); // Allocate buffer for section offset table NewSectOffset.SetZero(); // Initialize MInt NewVirtualAddress = 0; // Virtual address of new section as specified in Mach-O file // First loop through old sections for (oldsec = 0; oldsec < this->NSections; oldsec++) { NewSectIndex[oldsec] = 0; NewSectOffset[oldsec] = 0; // Get section name const char * sname = ""; uint32 namei = this->SectionHeaders[oldsec].sh_name; if (namei >= this->SecStringTableLen) { err.submit(2112); } else sname = this->SecStringTable + namei; if (cmd.DebugInfo == CMDL_DEBUG_STRIP) { // Check for debug section names if (strncmp(sname, ".note", 5) == 0 || strncmp(sname, ".comment", 8) == 0 || strncmp(sname, ".stab", 5) == 0 || strncmp(sname, ".debug", 6) == 0) { // Remove this section this->SectionHeaders[oldsec].sh_type = SHT_REMOVE_ME; cmd.CountDebugRemoved(); continue; } } if (cmd.ExeptionInfo == CMDL_EXCEPTION_STRIP) { // Check for exception section name if (strncmp(sname, ".eh_frame", 9) == 0) { // Remove this section this->SectionHeaders[oldsec].sh_type = SHT_REMOVE_ME; cmd.CountExceptionRemoved(); continue; } } // Search for program data sections only if (this->SectionHeaders[oldsec].sh_type != SHT_PROGBITS && this->SectionHeaders[oldsec].sh_type != SHT_NOBITS) { // Has no data. Ignore continue; } if (this->SectionHeaders[oldsec].sh_size == 0) { // Remove empty section // The linker has a bug with empty sections continue; } // Section index translation table NewSectIndex[oldsec] = newsec++; // Calculate virtual memory address of section. This address does not have // much to do with the final address, but it is needed in relocation entries. // Alignment int NewAlign = FloorLog2((uint32)this->SectionHeaders[oldsec].sh_addralign); if (NewAlign > 12) NewAlign = 12; // What is the limit for highest alignment? int AlignBy = 1 << NewAlign; // Align memory address NewVirtualAddress = (NewVirtualAddress + AlignBy - 1) & -(MInt)AlignBy; // Virtual memory address of new section NewSectOffset[oldsec] = NewVirtualAddress; // Increment memory address NewVirtualAddress += this->SectionHeaders[oldsec].sh_size; // Fix v. 2.14: Align end of memory address by 4 NewVirtualAddress = (NewVirtualAddress + 3) & MInt(-4); } // Store number of sections in new file NumSectionsNew = newsec; // Calculate file offset of first raw data RawDataOffset = sizeof(TMAC_header) + sizeof(TMAC_segment_command) + NumSectionsNew * sizeof(TMAC_section) + sizeof(MAC_symtab_command) + sizeof(MAC_dysymtab_command); // Align end of memory address by 4 NewVirtualAddress = (NewVirtualAddress + 3) & MInt(-4); // Make segment command TMAC_segment_command NewSegment; memset(&NewSegment, 0, sizeof(NewSegment)); NewSegment.cmd = (this->WordSize == 32) ? MAC_LC_SEGMENT : MAC_LC_SEGMENT_64; NewSegment.cmdsize = sizeof(TMAC_segment_command) + NumSectionsNew * sizeof(TMAC_section); NewSegment.fileoff = RawDataOffset; NewSegment.nsects = NumSectionsNew; NewSegment.maxprot = NewSegment.initprot = 7; // 1=read, 2=write, 4=execute NewSegment.vmsize = NewVirtualAddress; NewSegment.filesize = 0; // Changed later // put segment command in OutFile CommandOffset = ToFile.Push(&NewSegment, sizeof(NewSegment)); }
void WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture* texture, GLint level, GLint layer) { if (IsContextLost()) return; if (!ValidateFramebufferTarget(target, "framebufferTextureLayer")) return; if (!ValidateTextureLayerAttachment(attachment)) return ErrorInvalidEnumInfo("framebufferTextureLayer: attachment:", attachment); if (texture) { if (texture->IsDeleted()) { return ErrorInvalidValue("framebufferTextureLayer: texture must be a valid " "texture object."); } if (layer < 0) return ErrorInvalidValue("framebufferTextureLayer: layer must be >= 0."); if (level < 0) return ErrorInvalidValue("framebufferTextureLayer: level must be >= 0."); switch (texture->Target().get()) { case LOCAL_GL_TEXTURE_3D: if (uint32_t(layer) >= mImplMax3DTextureSize) { return ErrorInvalidValue("framebufferTextureLayer: layer must be < " "MAX_3D_TEXTURE_SIZE"); } if (uint32_t(level) > FloorLog2(mImplMax3DTextureSize)) { return ErrorInvalidValue("framebufferTextureLayer: layer mube be <= " "log2(MAX_3D_TEXTURE_SIZE"); } break; case LOCAL_GL_TEXTURE_2D_ARRAY: if (uint32_t(layer) >= mImplMaxArrayTextureLayers) { return ErrorInvalidValue("framebufferTextureLayer: layer must be < " "MAX_ARRAY_TEXTURE_LAYERS"); } if (uint32_t(level) > FloorLog2(mImplMaxTextureSize)) { return ErrorInvalidValue("framebufferTextureLayer: layer mube be <= " "log2(MAX_TEXTURE_SIZE"); } break; default: return ErrorInvalidOperation("framebufferTextureLayer: texture must be an " "existing 3D texture, or a 2D texture array."); } } WebGLFramebuffer* fb; switch (target) { case LOCAL_GL_FRAMEBUFFER: case LOCAL_GL_DRAW_FRAMEBUFFER: fb = mBoundDrawFramebuffer; break; case LOCAL_GL_READ_FRAMEBUFFER: fb = mBoundReadFramebuffer; break; default: MOZ_CRASH("Bad target."); } if (!fb) { return ErrorInvalidOperation("framebufferTextureLayer: cannot modify" " framebuffer 0."); } fb->FramebufferTextureLayer(attachment, texture, level, layer); }