Это подходящий способ использовать elf-loader в C? - PullRequest
0 голосов
/ 15 апреля 2020

1. Прежде всего, я хотел бы проверить себя, правильно ли я понимаю, что такое блоб в C в Linux:

All a binary blob is, is a pre-compiled shared object that is dynamically linked at runtime.

Это правильно? В общем, я должен получить файл .so и через elf-loader загрузить файл в текущее пространство памяти и запустить функцию. Я использовал этот elf-loader и его образец hello.so работает просто отлично.

2. Теперь я должен создать .so файл для запуска его через elf-loader. Как я уже отмечал здесь , мы не можем объединить файлы .so в один .so, но мы можем создать один файл .so из нескольких библиотек stati c (.a). И это то, что я выбрал (создание файла .so с использованием stati c libs).

3. Теперь я должен сказать, что у меня есть app-static.c, который является исходным файлом, который использует stati c libs freetype, libpng и zlib с именами libfreetype.a libpng.a libzlib.a соответственно. Поэтому я хочу сделать app-static.c архивом (stati c lib), а также объединить его с libfreetype.a libpng.a libzlib.a, а затем создать общий файл .so для загрузки через elf-loader.

4. Вот как я создаю объектный файл для выполнения слияния:

elvin@ubuntu:~/lab1KR/app$ gcc -c -fPIC app-static.c -I ../freetype/ -I ../libpng/ -I ../zlib/

Затем, когда объектный файл создан, я создаю c lib app-stati c. c

elvin@ubuntu:~/lab1KR/app$ ar -rsc libblob.a *.o

Затем я объединяю все 4 библиотеки:

elvin@ubuntu:~/lab1KR/app$ gcc -shared -fPIC -o c.so -Wl,--whole-archive libblob.a ../freetype/libfreetype.a ../libpng/libpng.a ../zlib/libzlib.a   -Wl,--no-whole-archive

Когда это сделано, я получаю c.so и хочу, чтобы он был загружен.

Для использования elf-loader требуется wheelc folder, main.c folder, elf_loader.c and elf_loader.h.

Я использую команду для создания elfloader.out:

elvin@ubuntu:~/lab1KR/app$ gcc -Wall -g -o elfloader elf_loader.c main.c wheelc/list.c -ldl

Это часть моего app-static.c (который теперь является stati c lib), который я хочу выполнить как образец hello.so

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

#include <malloc.h>
#include <math.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include<dirent.h>
#include <png.h>

...... .............

char* render_glyph(FT_Face* face, conf_t conf)
{
    FT_Library ft;
    FT_Error err;

    err = FT_Init_FreeType(&ft);
    if (err) return "freetype init error";

    err = FT_New_Face(ft, conf.font_file, 0, face);
    if (err == FT_Err_Unknown_File_Format)
        return "unknown font file format";
    else if (err)
        return "error reading font file";

    err = FT_Set_Pixel_Sizes(*face, 0, conf.size);
    if (err) return "error setting font size";

  int target_height;
  target_height = HEIGHT;
  FT_Vector     pen;
  FT_GlyphSlot  slot;
  slot = (*face)->glyph;
  pen.x = 300 * 64;
  pen.y = ( target_height - 200 ) * 64;
  int wid = 0;
    for (int i = 0; i < strlen(conf.text); ++i)
    {
        FT_UInt index = FT_Get_Char_Index(*face, conf.text[i]);
        //printf("FT_UInt index = %u\n", index);
        if (index == 0) return "no glyph found for char";
        err = FT_Load_Glyph(*face, index, FT_LOAD_DEFAULT);
        if (err) return "error loading glyph";
        err = FT_Render_Glyph((*face)->glyph, conf.anti_alias ?
                              FT_RENDER_MODE_NORMAL :
                              FT_RENDER_MODE_MONO);
        if (err) return "error rendering glyph";
        //draw_bitmap((*face)->glyph->bitmap);
        //draw_bitmap( &slot->bitmap, slot->bitmap_left, target_height - slot->bitmap_top );
        draw_bitmap( &slot->bitmap,
            slot->bitmap_left + wid,
            target_height - slot->bitmap_top-500);
        wid += slot->bitmap.width;
        pen.x += slot->advance.x;
        pen.y += slot->advance.y;
    }


    return NULL;
}

char* cool_render_png(char* out, int aa)
{
    //char buf[500]="\0";
    //strcat(buf,"../");
    //strcat(buf,out);
    FILE* f = fopen(out, "wb");
    if (!f)
        return "failed to open output file";
    png_structp png_out = png_create_write_struct(
                              PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_out)
        return "failed to create png write struct";

    png_infop png_info = png_create_info_struct(png_out);
    if (!png_info)
        return "failed to create png info struct";
        //printf("init_begin\n");
    //
    if (setjmp(png_jmpbuf(png_out)))
        return "png init io error";

    png_init_io(png_out, f);

    if (setjmp(png_jmpbuf(png_out)))
        return "IHDR write error";
        //printf("png_property\n");
    //
    png_set_IHDR(png_out,
                 png_info,
                 WIDTH,
                 HEIGHT,
                 aa ? 8 : 1,
                 PNG_COLOR_TYPE_GRAY,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png_out, png_info);
        //printf("another_png_property\n");
    //
    if (setjmp(png_jmpbuf(png_out)))
        return "png write error";

    int i;
    for (i = 0; i < HEIGHT; ++i)
    {
        //printf("\ti - %i\n",i);
        const unsigned char* rowptr = image[i];
        png_write_row(png_out, rowptr);
    }
        //printf("write\n");

    if (setjmp(png_jmpbuf(png_out)))
    {
        //printf("setjmp_error\n");
        return "png end error";
    }
        //printf("setjmp\n");
    png_write_end(png_out, NULL);
        //printf("png_write_end\n");

    fclose(f);
    return NULL;
}



int main1()
{
    clock_t begin =clock();
    conf_t conf;
    get_files_names();
    memset(&conf, 0, sizeof(conf_t));
    //conf->size = 72;
        //conf->font_file="../*.ttf";
        char buf[500]="\0";
        int k=0;
        for(k=0;k<files.rows;k++)
        {
            if(strstr(files.list_of_files[k],".ttf"))
            {
                //strcat(buf,"../");
                strcat(buf,files.list_of_files[k]);
            }
        }
        conf.font_file=(char*)calloc(strlen(buf)+1,sizeof(char));
        memcpy(conf.font_file,buf,(strlen(buf)+1)*sizeof(char));
        conf.name_png="default_name.png";
        conf.text="default";
        conf.size=72;

    FT_Face face;


    char* ft_err = render_glyph(&face, conf);
        //printf("render_glyph\n");
    if (ft_err != NULL)
    {
        printf("freetype error: %s\n", ft_err);
        return 2;
    }

    //printf("bitmap rows: %d, width: %d\n",
          // face->glyph->bitmap.rows,
          // face->glyph->bitmap.width);

    //char* png_err = render_png(face, "a.png", conf.anti_alias);
    char* png_err = cool_render_png(conf.name_png, conf.anti_alias);
        //printf("cool_render_png\n");


    if (png_err != NULL)
    {
        printf("png error: %s\n", png_err);
        return 3;
    }
    /*if(argc==1)
    {
        free(conf.font_file);
    }*/
    //printf("OK! File wa created!\n");
    clock_t end=clock();
    double time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
    printf("\n%f\n",time_spent);
    return 0;
}

7. Теперь мне нужно запустить elfloader и c .so:

elvin@ubuntu:~/lab1KR/app$ ./elfloader ./c.so main1

И у меня возникла ошибка при разрешении символа:

[DEBUG elf_loader.c:403] RELO JMP_SLOT   0x7f7b256f3a00 <-   0x7f7b254a9ae4 png_write_hIST
[DEBUG elf_loader.c:352] Processing 'c.so' relocation at index 318
[DEBUG elf_loader.c:258] SEARCH gzwrite in c.so@0x7f7b253f0000 (gnu)
[DEBUG elf_loader.c:281] FOUND gzwrite in c.so (0xc5ef1) 584
[DEBUG elf_loader.c:324] elf module c.so sym gzwrite s->st_value = 0xc5ef1, found in c.so, base = 0x7f7b253f0000, load_bias = 0x7f7b253f0000
[DEBUG elf_loader.c:403] RELO JMP_SLOT   0x7f7b256f3a08 <-   0x7f7b254b5ef1 gzwrite
[DEBUG elf_loader.c:352] Processing 'c.so' relocation at index 319

[DEBUG elf_loader.c:258] SEARCH trunc in c.so@0x7f7b253f0000 (gnu)
[DEBUG elf_loader.c:262] NOT FOUND trunc in c.so@0x7f7b253f0000 (gnu)
[ERROR elf_loader.c:368] cannot locate symbol "trunc" referenced by "c.so"...

[DEBUG elf_loader.c:924] [ finished linking c.so, ret=0 ]
[DEBUG elf_loader.c:49] name c.so: freeing soinfo @ 0x55fad58ed670
[ERROR main.c:95] load_elf_module c.so failed

Он находит все функции, но не может найти trunc. Я проверил, что это за trun c, используя usng grep, но не заметил, что trun c - это даже функция!

elvin@ubuntu:~/lab1KR$ grep -r -i "trunc"
Binary file app/c.so matches
zlib/deflate.c:             * is longer, truncate the previous match to a single literal.
zlib/zlib.h:   extra field, or that field truncated if extra_max is less than extra_len.
zlib/trees.c:#ifdef TRUNCATE_BLOCK
zlib/gzlib.c:                        O_TRUNC :
libpng/pngpread.c:         /* This may be a truncated stream (missing or
libpng/pngpread.c:            png_warning(png_ptr, "Truncated compressed data in IDAT");
libpng/pngwutil.c:          "Truncating profile to actual length in iCCP chunk");
libpng/pngrutil.c:            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
libpng/pngrutil.c:            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
libpng/pngrutil.c:          * sRGB and ITU Rec-709 both truncate the values for the D65 white
libpng/pngrutil.c:          * digits, the PNG spec gives the truncated value.
libpng/pngrutil.c:      png_warning(png_ptr, "Truncated zTXt chunk");
libpng/pngrutil.c:      png_warning(png_ptr, "Truncated iTXt chunk");
libpng/pngrutil.c:      png_warning(png_ptr, "Truncated iTXt chunk");
libpng/pngrutil.c:                     /* Get to here when the row_width truncates the final copy.
Binary file libpng/pngwutil.o matches
libpng/pngerror.c:    * happen is that the message will be truncated appropriately.
Binary file libpng/pngpread.o matches
Binary file libpng/libpng.so matches
libpng/pngmem.c: * result, we would be truncating potentially larger memory requests
Binary file libpng/libpng.a matches
libpng/pngrtran.c:                   * truncates the results.
Binary file libpng/png.o matches
Binary file libpng/pngrutil.o matches
freetype/ftraster.c:#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )
freetype/ftraster.c:      e1  = (Int)TRUNC( miny );
freetype/ftraster.c:      e1 = (Int)TRUNC( y1 );
freetype/ftraster.c:      e2  = (Int)TRUNC( maxy );
freetype/ftraster.c:      e2 = (Int)TRUNC( y2 );
freetype/ftraster.c:      ras.cProfile->start = TRUNC( e0 );
freetype/ftraster.c:    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
freetype/ftraster.c:    e1 = TRUNC( CEILING( x1 ) );
freetype/ftraster.c:      e2 = TRUNC( FLOOR( x2 ) );
freetype/ftraster.c:          e1 = TRUNC( e1 );
freetype/ftraster.c:    e1 = TRUNC( e1 );
freetype/ftraster.c:        e1 = TRUNC( e1 );
freetype/ftraster.c:          e1 = TRUNC( e1 );
freetype/ftraster.c:    e1 = TRUNC( e1 );
freetype/ftraster.c:      e1 = TRUNC( e1 ) / 2;
freetype/ftraster.c:    max_Y = (Short)TRUNC( ras.minY );
freetype/ftraster.c:    min_Y = (Short)TRUNC( ras.maxY );
freetype/ftraster.c:        ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
freetype/ftglyph.c:        if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
freetype/ftgrays.c:#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
freetype/ftgrays.c:    /* truncate the bounding box to integer pixels */
freetype/ftgrays.c:    ex1 = TRUNC( x1 );
freetype/ftgrays.c:    ex2 = TRUNC( x2 );
freetype/ftgrays.c:    ey1 = TRUNC( ras.last_ey );
freetype/ftgrays.c:    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
freetype/ftgrays.c:      TCoord  ex     = TRUNC( ras.x );
freetype/ftgrays.c:    gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
freetype/ftgrays.c:        gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
freetype/ftgrays.c:        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
freetype/ftgrays.c:        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
freetype/ftgrays.c:    gray_start_cell( worker, TRUNC( x ), TRUNC( y ) );
freetype/freetype/freetype.h:  /*    The glyph name is truncated to fit within the buffer if it is too  */
freetype/freetype/internal/ftmemory.h:  /* Return >= 1 if a truncation occurs.            */
freetype/freetype/ftglyph.h:  /*    FT_GLYPH_BBOX_TRUNCATE ::                                          */
freetype/freetype/ftglyph.h:    FT_GLYPH_BBOX_TRUNCATE  = 2,
freetype/freetype/ftglyph.h:  /*   ft_glyph_bbox_truncate  :: See @FT_GLYPH_BBOX_TRUNCATE.             */
freetype/freetype/ftglyph.h:#define ft_glyph_bbox_truncate   FT_GLYPH_BBOX_TRUNCATE
freetype/freetype/ftglyph.h:  /*    @FT_GLYPH_BBOX_TRUNCATE.                                           */
elvin@ubuntu:~/lab1KR$ 

Это просто препроцессор, а препроцессор не является функцией в все! Где я был не прав в создании блоба? Это правильный способ создать его? Если это то, почему я получаю ошибку? Как решить эту проблему? Не могли бы вы помочь мне? Заранее спасибо!

...