The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Изменить размер сегмента данных объектного файла, !*! CROSP, 08-Ноя-14, 00:19  [смотреть все]
  • Изменить размер сегмента данных объектного файла, !*! skb7, 02:09 , 08-Ноя-14 (1) +1
    > почему в объектнике сегмент данных (именно .data, а не
    > .rodata) записаны нули, если он этот сегмент вообще присутствует.
    > Хотя инициализированные переменные присутсвуют в сорцах.

    Возьмем вот такой код для примера, чтобы было о чем говорить:


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

    static int x = 0xa, y = 0xb, z = 0xc;

    int main(void)
    {
        int a = 0x1, b = 0x2, c = 0x3;
        int r = 0x0;

        scanf("%d\n", &r);

        r += a + b - c;
        r *= x + y - z;
        r -= z;

        printf("result: %d\n", r);

        return EXIT_SUCCESS;
    }

    Компилируем в объектник таким образом (именно таким):


    $ gcc -c -Wall -O0 main.c

    Смотрим, что в секции .data:


    $ objdump -D -j .data main.o

    Видим следующее:


    0000000000000000 <x>:
       0:    0a 00
    0000000000000004 <y>:
       4:    0b 00
    0000000000000008 <z>:
       8:    0c 00

    Делаем вывод, что всё работает как надо. Очевидно у вас нет глобальных данных, которые могли бы быть помещены в секцию ".data"? В моем случае в секцию ".data" попадают все глобальные инициализированные данные:


    static int x = 0xa, y = 0xb, z = 0xc;

  • Изменить размер сегмента данных объектного файла, !*! skb7, 02:30 , 08-Ноя-14 (2) +1
    > Изменить размер сегмента данных в объектном файле. То
    > есть в файле созданным без линковки gcc -c test.c.

    Далее текст для Debian-based дистрибутивов (Debian, Ubuntu, Mint).

    Утилиты для работы с системными вещами находятся в пакете "binutils". Можно посмотреть вот так:


    $ dpkg -L binutils | grep /usr/bin/

    Список наиболее часто используемых утилит (по крайней мере те, которые я часто использую):


    /usr/bin/size
    /usr/bin/addr2line
    /usr/bin/objcopy
    /usr/bin/as
    /usr/bin/readelf
    /usr/bin/nm
    /usr/bin/ar
    /usr/bin/strings
    /usr/bin/objdump
    /usr/bin/elfedit
    /usr/bin/strip
    /usr/bin/ld

    Уже по названию можно понять, что вам нужна "objcopy". Смотрим ман:


    $ man objcopy

    Далее ищем по слову "section" в мане. Жмем / и ищем по такому паттерну:


    ^ *--.*section

    Дальше ваша творческая работа :)

    Проверить размер ".data":


    $ size main.o | awk '{print $2}' | tail -1

    P.S. Если не получится -- пишите, будем думать дальше. Я такого раньше не делал (ибо бессмысленная задач), так что не уверен на 100% что именно objcopy надо юзать.

    P.P.S. Если справитесь -- не забудьте поделиться тут решением.

  • Изменить размер сегмента данных объектного файла, !*! pavlinux, 00:26 , 09-Ноя-14 (4) +1
  • Изменить размер сегмента данных объектного файла, !*! pavlinux, 00:28 , 09-Ноя-14 (5) +1
  • Изменить размер сегмента данных объектного файла, !*! pavlinux, 00:53 , 09-Ноя-14 (6) +1
    • Изменить размер сегмента данных объектного файла, !*! CROSP, 10:09 , 09-Ноя-14 (7) +1
      • Изменить размер сегмента данных объектного файла, !*! CROSP, 11:19 , 09-Ноя-14 (8) +1
        • Изменить размер сегмента данных объектного файла, !*! pavlinux, 03:30 , 10-Ноя-14 (10) +1
        • Изменить размер сегмента данных объектного файла, !*! skb7, 03:38 , 10-Ноя-14 (11) +1
          > Подскажите , а как с помощью этого ключа правильно определить смещение сегмента
          > данных чтобы задать в pad-to
          >
           
          > --gap-fill val --pad-to val
          >

          Вкратце посмотрел -- кажется действительно через objdump не выйдет изменить размер секции. Через ld, как предложил pavlinux, можно попробовать, но на выходе линкер дает бинарь, а не объектник, а вам надо объектник, как я понимаю (в качестве примера скрипта линкера можно юзать например /usr/lib/ldscripts/elf_x86_64.x).

          Есть другая идея -- дизасемблировать (через objdump) объектник в ассемблерный код и там изменить размер секции data, после чего скомпилировать асм в объектник. Проблема только в том, как дезасемблировать в такой код, который поймет gcc.

          Вот пример:

          1. Компилируем main.c в асм (main.s):


          $ gcc -S main.c -o main.S

          2. Меняем в main.S размеры переменных (например) в секции .data:


              .data
              .align 64
              .type    x, @object
              .size    x, 64
          x:
              .long    10
              .align 64
              .type    y, @object
              .size    y, 64
          y:
              .long    11
              .align 64
              .type    z, @object
              .size    z, 64
          z:
              .long    12

          т.е. align и size были 4 байта, я сделал 64 (первое что в голову пришло).

          3. Компилируем асм в объектник:


          $ gcc -c main.S

          Получаем объектник с измененной секцией ".data".
          В этой цепочке я изменял асм полученный из сырца, а не из объектника. Ваша задача понять, как получить из объектника такой асм файл, чтобы он мог быть скомпилирован обратно в объектник. Остальная процедура будет такая же, как у меня.

          • Изменить размер сегмента данных объектного файла, !*! skb7, 03:46 , 10-Ноя-14 (12) +1
            Нет, похоже никак не выйдет скомпилировать выхлоп objdump. Так что этот способ тоже не подходит. Вообще странное задание, кому может понадобиться изменять размер секции .data? Как вообще можно изменить её размер, разве что новых данных туда добавить, только они же не будут использованы кодом программы, короче бессмысленное задание немного. И вообще, какая тема? Линкер, системные утилиты, работа с асмом? Т.е. что предполагается должно быть использовано для решения задачи?
      • Изменить размер сегмента данных объектного файла, !*! pavlinux, 03:05 , 10-Ноя-14 (9) +1
        • Изменить размер сегмента данных объектного файла, !*! skb7, 03:59 , 10-Ноя-14 (14) +1
          В общем, я сделал, как pavlinux предложил, всё работает:

          1. Копируем соответствующий скрипт линкера в каталог с объектником:


          $ cp /usr/lib/ldscripts/elf_x86_64.x ./custom.ld

          2. Редактируем копию так, чтобы изменился размер секции ".data", например я просто выравнивание большое втыкнул (1024 байта):


            .data  :
            {
              *(.data .data.* .gnu.linkonce.d.*)
              SORT(CONSTRUCTORS)
              . = ALIGN(1024);
            }

          3. Перепаковуем линкером используя свой скрипт линкера:


          $ ld -T custom.ld -r main.o -o main2.o

          4. Смотрим размер .data в main2.o:


          $ size main2.o

          Первое что в голову пришло. Ну а дальше редактируем скрипт линкера в зависимости от того, что нужно получить.

  • Изменить размер сегмента данных объектного файла, !*! Fend2015, 14:23 , 13-Дек-14 (17)



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру