Beispiel #1
0
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;
    }
}
Beispiel #2
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;
}
Beispiel #4
0
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
Beispiel #5
0
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);
}