Esempio n. 1
0
File: main.c Progetto: Maschell/wut
void
__preinit_user(MEMHeapHandle *mem1,
               MEMHeapHandle *foreground,
               MEMHeapHandle *mem2)
{
   uint32_t addr, size;

   MEMAllocFromDefaultHeap = CustomAllocFromDefaultHeap;
   MEMAllocFromDefaultHeapEx = CustomAllocFromDefaultHeapEx;
   MEMFreeToDefaultHeap = CustomFreeToDefaultHeap;

   if (OSGetForegroundBucket(NULL, NULL)) {
      OSGetMemBound(OS_MEM1, &addr, &size);
      *mem1 = MEMCreateFrmHeapEx((void *)addr, size, 0);

      OSGetForegroundBucketFreeArea(&addr, &size);
      *foreground = MEMCreateFrmHeapEx((void *)addr, size, 0);
   }

   OSGetMemBound(OS_MEM2, &addr, &size);
   sCustomHeap = MEMCreateExpHeapEx((void *)addr, size, MEM_HEAP_FLAG_USE_LOCK);
   sCustomHeapAddr = addr;
   sCustomHeapSize = size;
   *mem2 = sCustomHeap;

   OSDynLoad_SetAllocator(CustomDynLoadAlloc, CustomDynLoadFree);
   OSDynLoad_SetTLSAllocator(CustomDynLoadAlloc, CustomDynLoadFree);
}
Esempio n. 2
0
// TODO: Move to coreinit::internal
void
CoreInitDefaultHeap()
{
   be_val<uint32_t> addr, size;

   // Create expanding heap for MEM2
   OSGetMemBound(OSMemoryType::MEM2, &addr, &size);
   auto mem2 = MEMCreateExpHeap(make_virtual_ptr<ExpandedHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::MEM2, reinterpret_cast<CommonHeap*>(mem2));

   // Create frame heap for MEM1
   OSGetMemBound(OSMemoryType::MEM1, &addr, &size);
   auto mem1 = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::MEM1, reinterpret_cast<CommonHeap*>(mem1));

   // Create frame heap for Foreground
   OSGetForegroundBucketFreeArea(&addr, &size);
   auto fg = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::FG, reinterpret_cast<CommonHeap*>(fg));
}
Esempio n. 3
0
void
Loader::initialise(ppcsize_t maxCodeSize)
{
   // Get the MEM2 Region
   be_val<uint32_t> mem2start, mem2size;
   OSGetMemBound(OSMemoryType::MEM2, &mem2start, &mem2size);

   // Allocate MEM2 Region
   gMemory.alloc(mem2start, mem2size);

   // Steal some space for code heap
   mCodeHeap = new TeenyHeap(gMemory.translate(mem2start), maxCodeSize);

   // Update MEM2 to ignore the code heap region
   OSSetMemBound(OSMemoryType::MEM2, mem2start + maxCodeSize, mem2size - maxCodeSize);
}
Esempio n. 4
0
static MemoryList *
findListContainingHeap(CommonHeap *heap)
{
   be_val<uint32_t> start, size, end;
   OSGetForegroundBucket(&start, &size);
   end = start + size;

   if (heap->dataStart >= start && heap->dataEnd < end) {
      return gForegroundMemlist;
   } else {
      OSGetMemBound(OSMemoryType::MEM1, &start, &size);
      end = start + size;

      if (heap->dataStart >= start && heap->dataEnd < end) {
         return gMEM1Memlist;
      } else {
         return gMEM2Memlist;
      }
   }
}
Esempio n. 5
0
static MemoryList *
findListContainingBlock(void *block)
{
   be_val<uint32_t> start, size, end;
   uint32_t addr = gMemory.untranslate(block);
   OSGetForegroundBucket(&start, &size);
   end = start + size;

   if (addr >= start && addr < end) {
      return gForegroundMemlist;
   } else {
      OSGetMemBound(OSMemoryType::MEM1, &start, &size);
      end = start + size;

      if (addr >= start && addr < end) {
         return gMEM1Memlist;
      } else {
         return gMEM2Memlist;
      }
   }
}
Esempio n. 6
0
bool
Loader::loadRPL(UserModule &module, const char *buffer, size_t size)
{
   auto in = BigEndianView { buffer, size };
   auto header = elf::Header { };
   auto info = elf::FileInfo { };
   auto sections = std::vector<elf::Section> { };

   // Read header
   if (!elf::readHeader(in, header)) {
      gLog->error("Failed elf::readHeader");
      return false;
   }

   // Check it is a CAFE abi rpl
   if (header.abi != elf::EABI_CAFE) {
      gLog->error("Unexpected elf abi found {:02x} expected {:02x}", header.abi, elf::EABI_CAFE);
      return false;
   }

   // Read sections
   if (!elf::readSections(in, header, sections)) {
      gLog->error("Failed elf::readSections");
      return false;
   }

   // Process sections, find our data and code sections
   processSections(module, sections, sections[header.shstrndx].data.data());

   // Update EntryInfo
   loadFileInfo(info, sections);
   module.entryPoint = header.entry;
   module.defaultStackSize = info.stackSize;

   // Allocate code & data sections in memory
   auto codeStart = module.codeAddressRange.first;
   auto codeSize = module.maxCodeSize;
   gMemory.alloc(codeStart, codeSize); // TODO: Append code to end of other loaded code sections

   auto dataStart = alignUp(codeStart + codeSize, 4096);
   auto dataSize = alignUp(module.dataAddressRange.second - module.dataAddressRange.first, 4096);
   auto dataEnd = dataStart + dataSize;
   gMemory.alloc(dataStart, dataSize); // TODO: Use OSDynLoad_MemAlloc for data section allocation

   // Update MEM2 memory bounds
   be_val<uint32_t> mem2start, mem2size;
   OSGetMemBound(OSMemoryType::MEM2, &mem2start, &mem2size);
   OSSetMemBound(OSMemoryType::MEM2, dataEnd, mem2size - (dataEnd - mem2start));

   // Relocate sections
   relocateSections(sections, module.codeAddressRange.first, codeStart, module.dataAddressRange.first, dataStart);

   module.codeAddressRange.first = codeStart;
   module.codeAddressRange.second = codeStart + codeSize;

   module.dataAddressRange.first = dataStart;
   module.dataAddressRange.second = dataStart + dataSize;

   // Relocate entry point
   for (auto i = 0u; i < sections.size(); ++i) {
      auto &section = sections[i];

      if (section.header.addr <= header.entry && section.header.addr + section.data.size() > header.entry) {
         auto offset = section.section->address - section.header.addr;
         module.entryPoint = header.entry + offset;
         break;
      }
   }

   // Load sections into memory
   loadSections(sections);

   // Process small data sections
   processSmallDataSections(module);

   // Process symbols
   // TODO: Support more than one symbol section?
   for (auto i = 0u; i < sections.size(); ++i) {
      auto &section = sections[i];

      if (section.header.type != elf::SHT_SYMTAB) {
         continue;
      }

      processSymbols(module, section, sections);
   }

   // Process relocations
   for (auto i = 0u; i < sections.size(); ++i) {
      auto &section = sections[i];

      if (section.header.type != elf::SHT_RELA) {
         continue;
      }

      processRelocations(module, section, sections);
   }
   
   if (0) {
      // Print address ranges
      gLog->debug("Loaded module!");
      gLog->debug("Code {:08x} -> {:08x}", module.codeAddressRange.first, module.codeAddressRange.second);
      gLog->debug("Data {:08x} -> {:08x}", module.dataAddressRange.first, module.dataAddressRange.second);

      // Print all sections
      gLog->debug("Sections:");

      for (auto i = 0u; i < module.sections.size(); ++i) {
         auto section = module.sections[i];
         gLog->debug("{:08x} {} {:x}", section->address, section->name, section->size);
      }
      
      // Print all symbols
      gLog->debug("Symbols:");

      for (auto i = 0u; i < module.symbols.size(); ++i) {
         auto symbol = module.symbols[i];

         if (symbol && symbol->name.size()) {
            gLog->debug("{:08x} {}", symbol->address, symbol->name);
         }
      }
   }

   return true;
}