Changeset 1544


Ignore:
Timestamp:
Oct 7, 2004, 8:36:35 AM (21 years ago)
Author:
bird
Message:

Implemented lazyimp for a.out.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/emximp/emximp.c

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r1543 r1544  
    8888static int opt_q;
    8989static int opt_s;
     90static int opt_lazy;
    9091static enum modes mode = M_NONE;
    9192static long mod_lbl;
     
    129130  puts ("  -q   Be quiet");
    130131  puts ("  -m   Call _mcount for profiling");
     132  puts ("  -l   Lazy loading and resolving");
    131133  exit (1);
    132134}
     
    181183
    182184
    183 #if 0 /* not used */
    184185static void *xrealloc (void *p, size_t n)
    185186{
     
    191192  return q;
    192193}
    193 #endif
    194194
    195195
     
    615615static struct nlist aout_sym_tab[6];
    616616
    617 static byte aout_text[64];
     617static byte aout_text[300];
    618618static int aout_text_size;
    619619
    620 static struct relocation_info aout_treloc_tab[2];
     620static byte aout_data[300];
     621static int aout_data_size;
     622
     623static struct relocation_info aout_treloc_tab[7];
    621624static int aout_treloc_count;
     625
     626static struct relocation_info aout_dreloc_tab[7];
     627static int aout_dreloc_count;
    622628
    623629static int aout_size;
     
    629635  aout_sym_count = 0;
    630636  aout_text_size = 0;
     637  aout_data_size = 0;
    631638  aout_treloc_count = 0;
     639  aout_dreloc_count = 0;
    632640}
    633641
     
    684692}
    685693
     694static void aout_data_byte (byte b)
     695{
     696  if (aout_data_size >= sizeof (aout_data))
     697    error ("a.out data segment overflow");
     698  aout_data[aout_data_size++] = b;
     699}
     700
     701static void aout_data_dword (dword d)
     702{
     703  aout_data_byte ((d >> 0) & 0xff);
     704  aout_data_byte ((d >> 8) & 0xff);
     705  aout_data_byte ((d >> 16) & 0xff);
     706  aout_data_byte ((d >> 24) & 0xff);
     707}
     708
     709static void aout_dreloc (dword address, int symbolnum, int pcrel, int length,
     710                         int ext)
     711{
     712  if (aout_dreloc_count >= sizeof (aout_dreloc_tab) / sizeof (struct relocation_info))
     713    error ("a.out data relocation buffer overflow");
     714  aout_dreloc_tab[aout_dreloc_count].r_address = address;
     715  aout_dreloc_tab[aout_dreloc_count].r_symbolnum = symbolnum;
     716  aout_dreloc_tab[aout_dreloc_count].r_pcrel = pcrel;
     717  aout_dreloc_tab[aout_dreloc_count].r_length = length;
     718  aout_dreloc_tab[aout_dreloc_count].r_extern = ext;
     719  aout_dreloc_tab[aout_dreloc_count].r_pad = 0;
     720  ++aout_dreloc_count;
     721}
    686722
    687723static void aout_finish (void)
     
    689725  while (aout_text_size & 3)
    690726    aout_text_byte (0x90);
    691   aout_size = (sizeof (struct exec) + aout_text_size
     727  while (aout_data_size & 3)
     728    aout_data_byte (0);
     729  aout_size = (sizeof (struct exec) + aout_text_size + aout_data_size
    692730               + aout_treloc_count * sizeof (struct relocation_info)
     731               + aout_dreloc_count * sizeof (struct relocation_info)
    693732               + aout_sym_count * sizeof (aout_sym_tab[0])
    694733               + aout_str_size);
     
    704743  N_SET_FLAGS (ao, 0);
    705744  ao.a_text = aout_text_size;
    706   ao.a_data = 0;
     745  ao.a_data = aout_data_size;
    707746  ao.a_bss = 0;
    708747  ao.a_syms = aout_sym_count * sizeof (aout_sym_tab[0]);
    709748  ao.a_entry = 0;
    710749  ao.a_trsize = aout_treloc_count * sizeof (struct relocation_info);
    711   ao.a_drsize = 0;
     750  ao.a_drsize = aout_dreloc_count * sizeof (struct relocation_info);;
    712751  fwrite (&ao, 1, sizeof (ao), out_file);
    713   fwrite (aout_text, 1, aout_text_size, out_file);
     752  fwrite (aout_text, aout_text_size, 1, out_file);
     753  fwrite (aout_data, aout_data_size, 1, out_file);
    714754  fwrite (aout_treloc_tab, aout_treloc_count, sizeof (struct relocation_info), out_file);
     755  fwrite (aout_dreloc_tab, aout_dreloc_count, sizeof (struct relocation_info), out_file);
    715756  fwrite (aout_sym_tab, aout_sym_count, sizeof (aout_sym_tab[0]), out_file);
    716757  *(dword *)aout_str_tab = aout_str_size;
     
    719760
    720761
     762static void write_a_lazyldr (const char *resolver_sym, const char *mod_name)
     763{
     764    char  tmp[257];
     765    dword *ptr_hmod_fixup, *ptr_name_fixup;
     766    const char *p;
     767    static char *done = NULL;
     768    if (done)
     769      {
     770        if (strstr (done, resolver_sym))
     771          return;
     772        done = xrealloc (done, strlen (resolver_sym) + 1);
     773        strcat (done, resolver_sym);
     774      }
     775    else
     776      done = xstrdup (resolver_sym);
     777
     778    /* Write module resolver object
     779        .text
     780        .globl ___lazyimp_doscalls_resolver
     781    ___lazyimp_doscalls_resolver:
     782        push    name
     783        push    hmod
     784        jmp     ___lazyimp_resolver
     785    name:
     786        .asciiz "DOSCALLS"
     787        .byte 0
     788
     789        .data
     790    hmod:
     791        .long   0
     792    */
     793    aout_init ();
     794    aout_sym (resolver_sym, N_TEXT|N_EXT, 0, 0, aout_text_size); /* .globl DosRead */
     795    aout_text_byte (0x68);              /* push name */
     796    aout_treloc (aout_text_size, N_TEXT, 0, 2, 0);
     797    ptr_name_fixup = (dword *)&aout_text[aout_text_size];
     798    aout_text_dword (0);
     799
     800    aout_text_byte (0x68);              /* push pfn */
     801    aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
     802    ptr_hmod_fixup = (dword *)&aout_text[aout_text_size];
     803    aout_text_dword (0);
     804
     805    aout_text_byte (0xe9);            /* jmp ___lazyimp_resolver */
     806    aout_treloc (aout_text_size, aout_sym ("___lazyimp_resolver", N_EXT, 0, 0, 0), 1, 2, 1);
     807    aout_text_dword (0 - (aout_text_size + 4));
     808
     809    *ptr_name_fixup = aout_text_size;   /* name: .ascii */
     810    strcpy (tmp, mod_name);
     811    strupr (tmp);
     812    for (p = tmp; *p; p++)
     813      aout_text_byte(*p);
     814    aout_text_byte(0);
     815
     816    while (aout_text_size & 3)
     817        aout_text_byte (0xcc);
     818
     819    *ptr_hmod_fixup = aout_text_size;   /* hmod: .long 0 */
     820    aout_data_dword (0);
     821
     822
     823    aout_finish ();
     824    sprintf (tmp, "LAZYMOD#%ld", seq_no);
     825    write_ar (tmp, aout_size);
     826    aout_write ();
     827    finish_ar ();
     828    seq_no++;
     829    if (ferror (out_file))
     830      write_error (out_fname);
     831}
     832
     833
    721834static void write_a_import (const char *func_name, const char *mod_name,
    722835                            int ordinal, const char *proc_name)
     
    726839  dword fixup_mcount, fixup_import;
    727840
    728   aout_init ();
    729841  /* #425: Underscore is gone. (was "_%s") */
    730842  sprintf (tmp2, "%s", func_name);
    731   if (profile_flag && strncmp (func_name, "_16_", 4) != 0)
    732     {
    733       sym_entry = aout_sym (tmp2, N_TEXT|N_EXT, 0, 0, aout_text_size);
    734       sym_mcount = aout_sym ("__mcount", N_EXT, 0, 0, 0);
    735 
    736       /* Use, say, "_$U_DosRead" for "DosRead" to import the
    737          non-profiled function. */
    738       sprintf (tmp2, "__$U_%s", func_name);
    739       sym_import = aout_sym (tmp2, N_EXT, 0, 0, 0);
    740 
    741       aout_text_byte (0x55);    /* push ebp */
    742       aout_text_byte (0x89);    /* mov ebp, esp */
    743       aout_text_byte (0xe5);
    744       aout_text_byte (0xe8);    /* call _mcount*/
    745       fixup_mcount = aout_text_size;
     843  /*
     844   * Lazily resolved dynamic import.
     845   */
     846  if (opt_lazy && strncmp (func_name, "_16_", 4) != 0)
     847    {
     848      int   off_name, off_resolver;
     849      dword *fixup_ptr1, *fixup_ptr2;
     850      char *p;
     851
     852      /* create module resolver object first. */
     853      sprintf (tmp1, "___lazyldr_%s_resolver", mod_name);
     854      write_a_lazyldr (tmp1, mod_name);
     855
     856      /* Write import object
     857          .data
     858      pfn:
     859          .long   resolve
     860          .text
     861          .globl DosRead
     862      DosRead:
     863          jmp     *(pfn)
     864      name:
     865          .asciiz "DosRead"
     866          .byte 0
     867      resolve:
     868          push    name
     869          push    pfn
     870          jmp     ___lazyimp_doscalls_resolver
     871      */
     872      aout_init ();
     873      aout_sym (tmp2, N_TEXT|N_EXT, 0, 0, aout_text_size); /* .globl DosRead */
     874      strlwr (tmp1);
     875      aout_text_byte (0xff);            /* jmp *(pfn) */
     876      aout_text_byte (0x25);
     877      aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
     878      fixup_ptr1 = (dword *)&aout_text[aout_text_size];
     879      aout_text_dword (aout_data_size);
     880
     881      if (proc_name)
     882        {
     883          off_name = aout_text_size;        /* name: .ascii */
     884          for (p = tmp2; *p; p++)
     885            aout_text_byte(*p);
     886          aout_text_byte(0);
     887          aout_text_byte (0xcc);
     888        }
     889
     890      off_resolver = aout_text_size;    /* resolve: push name / ordinal */
     891      aout_text_byte (0x68);
     892      if (proc_name)
     893        {
     894          aout_treloc (aout_text_size, N_TEXT, 0, 2, 0);
     895          aout_text_dword (off_name);
     896        }
     897      else
     898        aout_text_dword (ordinal);
     899
     900      aout_text_byte (0x68);            /* resolve: push pfn */
     901      aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
     902      fixup_ptr2 = (dword *)&aout_text[aout_text_size];
     903      aout_text_dword (0);
     904
     905      aout_text_byte (0xe9);            /* jmp ___lazyimp_????_resolver */
     906      aout_treloc (aout_text_size, aout_sym (tmp1, N_EXT, 0, 0, 0), 1, 2, 1);
    746907      aout_text_dword (0 - (aout_text_size + 4));
    747       aout_text_byte (0x5d);    /* pop ebp */
    748       aout_text_byte (0xe9);    /* jmp _$U_DosRead*/
    749       fixup_import = aout_text_size;
    750       aout_text_dword (0 - (aout_text_size + 4));
    751 
    752       aout_treloc (fixup_mcount, sym_mcount, 1, 2, 1);
    753       aout_treloc (fixup_import, sym_import, 1, 2, 1);
    754     }
    755   sprintf (tmp1, "IMPORT#%ld", seq_no);
    756   if (proc_name == NULL)
    757     sprintf (tmp3, "%s=%s.%d", tmp2, mod_name, ordinal);
     908      while (aout_text_size & 3)
     909          aout_text_byte (0xcc);
     910
     911      *fixup_ptr1 = aout_text_size;
     912      *fixup_ptr2 = aout_text_size;
     913      aout_dreloc (aout_data_size, N_TEXT, 0, 2, 0); /* pfn: .long resolve */
     914      aout_data_dword (off_resolver);
     915      sprintf (tmp1, "LAZYIMP#%ld", seq_no);
     916    }
     917  /*
     918   * Static load time import.
     919   */
    758920  else
    759     sprintf (tmp3, "%s=%s.%s", tmp2, mod_name, proc_name);
    760   aout_sym (tmp2, N_IMP1|N_EXT, 0, 0, 0);
    761   aout_sym (tmp3, N_IMP2|N_EXT, 0, 0, 0);
     921    {
     922      aout_init ();
     923      if (profile_flag && strncmp (func_name, "_16_", 4) != 0)
     924        {
     925          sym_entry = aout_sym (tmp2, N_TEXT|N_EXT, 0, 0, aout_text_size);
     926          sym_mcount = aout_sym ("__mcount", N_EXT, 0, 0, 0);
     927
     928          /* Use, say, "_$U_DosRead" for "DosRead" to import the
     929             non-profiled function. */
     930          sprintf (tmp2, "__$U_%s", func_name);
     931          sym_import = aout_sym (tmp2, N_EXT, 0, 0, 0);
     932
     933          aout_text_byte (0x55);    /* push ebp */
     934          aout_text_byte (0x89);    /* mov ebp, esp */
     935          aout_text_byte (0xe5);
     936          aout_text_byte (0xe8);    /* call _mcount*/
     937          fixup_mcount = aout_text_size;
     938          aout_text_dword (0 - (aout_text_size + 4));
     939          aout_text_byte (0x5d);    /* pop ebp */
     940          aout_text_byte (0xe9);    /* jmp _$U_DosRead*/
     941          fixup_import = aout_text_size;
     942          aout_text_dword (0 - (aout_text_size + 4));
     943
     944          aout_treloc (fixup_mcount, sym_mcount, 1, 2, 1);
     945          aout_treloc (fixup_import, sym_import, 1, 2, 1);
     946        }
     947      if (proc_name == NULL)
     948        sprintf (tmp3, "%s=%s.%d", tmp2, mod_name, ordinal);
     949      else
     950        sprintf (tmp3, "%s=%s.%s", tmp2, mod_name, proc_name);
     951      aout_sym (tmp2, N_IMP1|N_EXT, 0, 0, 0);
     952      aout_sym (tmp3, N_IMP2|N_EXT, 0, 0, 0);
     953      sprintf (tmp1, "IMPORT#%ld", seq_no);
     954    }
     955
    762956  aout_finish ();
    763957  write_ar (tmp1, aout_size);
     
    12761470  opterr = 0;
    12771471  optind = 1;
    1278   while ((c = getopt (argc, argv, "a::b:mo:p:qsP:")) != EOF)
     1472  while ((c = getopt (argc, argv, "a::b:lmo:p:qsP:")) != EOF)
    12791473    {
    12801474      switch (c)
     
    12941488              base_len = 0;
    12951489            }
     1490          break;
     1491        case 'l':
     1492          opt_lazy = TRUE;
    12961493          break;
    12971494        case 'm':
Note: See TracChangeset for help on using the changeset viewer.