Domanda

Come un esercizio di programmazione, sto scrivendo un mark-and-sweep garbage collector in C. Ho desiderio di eseguire la scansione del segmento di dati (variabili globali, etc.) per puntatori a memoria allocata, ma non so come arrivare la gamma di indirizzi di questo segmento. Come potrei fare questo?

È stato utile?

Soluzione

I limiti per il testo (codice del programma) ei dati per Linux (e altri Unix):

#include <stdio.h>
#include <stdlib.h>

/* these are in no header file, and on some
systems they have a _ prepended 
These symbols have to be typed to keep the compiler happy
Also check out brk() and sbrk() for information
about heap */

extern char  etext, edata, end; 

int
main(int argc, char **argv)
{
    printf("First address beyond:\n");
    printf("    program text segment(etext)      %10p\n", &etext);
    printf("    initialized data segment(edata)  %10p\n", &edata);
    printf("    uninitialized data segment (end) %10p\n", &end);

    return EXIT_SUCCESS;
}

Quando tali simboli provengono da: Dove sono i simboli etext, edata e alla fine ha definito?

Altri suggerimenti

Se si sta lavorando su Windows, poi ci sono le API di Windows che vi aiutano.

//store the base address the loaded Module
dllImageBase = (char*)hModule; //suppose hModule is the handle to the loaded Module (.exe or .dll)

//get the address of NT Header
IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);

//after Nt headers comes the table of section, so get the addess of section table
IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *) (pNtHdr + 1);

ImageSectionInfo *pSectionInfo = NULL;

//iterate through the list of all sections, and check the section name in the if conditon. etc
for ( int i = 0 ; i < pNtHdr->FileHeader.NumberOfSections ; i++ )
{
     char *name = (char*) pSectionHdr->Name;
     if ( memcmp(name, ".data", 5) == 0 )
     {
          pSectionInfo = new ImageSectionInfo(".data");
          pSectionInfo->SectionAddress = dllImageBase + pSectionHdr->VirtualAddress;

          **//range of the data segment - something you're looking for**
          pSectionInfo->SectionSize = pSectionHdr->Misc.VirtualSize;
          break;
      }
      pSectionHdr++;
}

Definisci ImageSectionInfo come,

struct ImageSectionInfo
{
      char SectionName[IMAGE_SIZEOF_SHORT_NAME];//the macro is defined WinNT.h
      char *SectionAddress;
      int SectionSize;
      ImageSectionInfo(const char* name)
      {
            strcpy(SectioName, name); 
       }
};

Ecco un completo programma di minima, console Win32 è possibile eseguire in Visual Studio che dimostra l'utilizzo delle API di Windows:

#include <stdio.h>
#include <Windows.h>
#include <DbgHelp.h>
#pragma comment( lib, "dbghelp.lib" )

void print_PE_section_info(HANDLE hModule) // hModule is the handle to a loaded Module (.exe or .dll)
{
   // get the location of the module's IMAGE_NT_HEADERS structure
   IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);

   // section table immediately follows the IMAGE_NT_HEADERS
   IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr + 1);

   const char* imageBase = (const char*)hModule;
   char scnName[sizeof(pSectionHdr->Name) + 1];
   scnName[sizeof(scnName) - 1] = '\0'; // enforce nul-termination for scn names that are the whole length of pSectionHdr->Name[]

   for (int scn = 0; scn < pNtHdr->FileHeader.NumberOfSections; ++scn)
   {
      // Note: pSectionHdr->Name[] is 8 bytes long. If the scn name is 8 bytes long, ->Name[] will
      // not be nul-terminated. For this reason, copy it to a local buffer that's nul-terminated
      // to be sure we only print the real scn name, and no extra garbage beyond it.
      strncpy(scnName, (const char*)pSectionHdr->Name, sizeof(pSectionHdr->Name));

      printf("  Section %3d: %p...%p %-10s (%u bytes)\n",
         scn,
         imageBase + pSectionHdr->VirtualAddress,
         imageBase + pSectionHdr->VirtualAddress + pSectionHdr->Misc.VirtualSize - 1,
         scnName,
         pSectionHdr->Misc.VirtualSize);
      ++pSectionHdr;
   }
}

// For demo purpopses, create an extra constant data section whose name is exactly 8 bytes long (the max)
#pragma const_seg(".t_const") // begin allocating const data in a new section whose name is 8 bytes long (the max)
const char const_string1[] = "This string is allocated in a special const data segment named \".t_const\".";
#pragma const_seg() // resume allocating const data in the normal .rdata section

int main(int argc, const char* argv[])
{
   print_PE_section_info(GetModuleHandle(NULL)); // print section info for "this process's .exe file" (NULL)
}

Questa pagina può essere utile se siete interessati in altri usi della biblioteca DbgHelp.

Si può leggere il formato dell'immagine PE qui, per conoscere in dettaglio. Una volta capito il formato PE, sarete in grado di lavorare con il codice di cui sopra, e può anche modificarlo per soddisfare le vostre necessità.

  • Formato PE

Peering All'interno del PE: Una panoramica di Portable Format file eseguibile Win32

uno sguardo in profondità nella Win32 Portable Executable Formato file, parte 1

uno sguardo in profondità nella Win32 Portable Executable Formato file, parte 2

  • API di Windows e strutture

IMAGE_SECTION_HEADER Struttura

ImageNtHeader Funzione

IMAGE_NT_HEADERS Struttura

Credo che questo si contribuirebbe a grande misura, e il resto è possibile la ricerca da soli: -)

Tra l'altro, è anche possibile vedere questa discussione, come tutti questi sono legati in qualche modo a questo:

Scenario: variabili globali in DLL che viene utilizzato da applicazioni multi-threaded

Dal momento che probabilmente dovrete rendere il vostro garbage collector l'ambiente in cui viene eseguito il programma, è possibile ottenere dal file elfo direttamente.

Caricare il file che l'eseguibile è venuto da e analizzare le intestazioni PE, per Win32. Non ho idea circa su altri sistemi operativi. Ricordate che se il vostro programma si compone di più file (ad esempio DLL) è possibile avere più segmenti di dati.

Per iOS è possibile utilizzare questa soluzione . Essa mostra come trovare la gamma segmento di testo, ma è possibile modificare facilmente per trovare qualsiasi segmento che ti piace.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top