The OpenNET Project / Index page

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

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Изменить размер сегмента данных объектного файла"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Изменить размер сегмента данных объектного файла"  +/
Сообщение от CROSP (ok) on 08-Ноя-14, 00:19 
Здравствуйте, есть такая задача. Изменить размер сегмента данных в объектном файле. То есть в файле созданным без линковки gcc -c test.c. Сразу скажу честно, задание учебное. Я понимаю принцип расположения всех сегментов,как их посмотреть, как они буду отображены в памяти ( но тут сейчас не все так однозначно, так как используется ASLR). Знаю системные вызовы brk / sbrk , но они же исполняютс в рантайме из программы. Как изменить размер объектного файла + чтобы не повредить программу. Еще такой вопрос, почему в объектнике сегмент данных (именно .data, а не .rodata) записаны нули, если он этот сегмент вообще присутствует. Хотя инициализированные переменные присутсвуют в сорцах. Подскажите пожалуйста, куда смотреть, чтобы сделать задание и объясните на счет вопросов. Спасибо заранее.
Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 08-Ноя-14, 02:09 
> почему в объектнике сегмент данных (именно .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;

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 08-Ноя-14, 02:30 
> Изменить размер сегмента данных в объектном файле. То
> есть в файле созданным без линковки 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. Если справитесь -- не забудьте поделиться тут решением.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "Изменить размер сегмента данных объектного файла"  +/
Сообщение от CROSP (ok) on 08-Ноя-14, 11:36 
>[оверквотинг удален]
>
> Дальше ваша творческая работа :)
> Проверить размер ".data":
>
 
> $ size main.o | awk '{print $2}' | tail -1
>

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

Спасибо большое за ответ. Вот пробовал много способов которые нашел в мане.
Первое что попробовал это

 

--change-section-address section{=,+,-}val
--adjust-section-vma section{=,+,-}val

Насколько я понял этот ключ просто меняет адрес на указанную величину, то есть сам размер остается тот же, но адрес меняется. Пробовал различные комбинации, просто назначает другие адреса.
Второе что нашел это

 
--gap-fill val --pad-to val

Этот ключ заполняет указанными значениями от определенной секции со смещением, до указанного смещения в pad-to val. Проверил работает , увеличивает размер сегмента, заполняя его FF.
Но как уменьшить размер определенного сегменат.
Еще нашел что можно выделит заранее место для хипа или стека, но для данных нельзя, но это и логично вообще.
Подскажите пожалуйста, что можно еще попробовать
Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от pavlinux (ok) on 09-Ноя-14, 00:26 
>  Подскажите пожалуйста, куда смотреть,

Мануал на ld или какой вы там линкер изучаете.

> чтобы сделать задание

$ echo'SECTIONS {.data : { *(.data) } += 0x12345678}' > script.ld;
$ ld -T script.ld  тут.o куча.о объектников.о системных.о и.o -lc

Скрипт не тестил, мож придётся ALIGN делать, и добавлять дыру такого же размера после себя, ... короча сам. :)


> и объясните на ...

Это уже платно.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

5. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от pavlinux (ok) on 09-Ноя-14, 00:28 
во, даже тут нашел http://www.opennet.me/docs/RUS/gnu_ld/gnuld-3.html
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

6. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от pavlinux (ok) on 09-Ноя-14, 00:53 
> Изменить размер сегмента данных в объектном файле.

Я знаю правильный ответ: Купите оперативки, жмоты!!! :D

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

7. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от CROSP email(ok) on 09-Ноя-14, 10:09 
>> Изменить размер сегмента данных в объектном файле.
> Я знаю правильный ответ: Купите оперативки, жмоты!!! :D

Спасибо Вам большое за ответ. Но дело в том что надо сам объектный файл изменить так чтобы уменьшился размер сегмента данных. А на сколько я понимаю линковщик создаст уже исполняемый файлы.

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от CROSP email(ok) on 09-Ноя-14, 11:19 
Подскажите , а как с помощью этого ключа правильно определить смещение сегмента данных чтобы задать в pad-to

--gap-fill val --pad-to val

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

10. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от pavlinux (ok) on 10-Ноя-14, 03:30 
> Подскажите , а как с помощью этого ключа правильно определить смещение сегмента
> данных чтобы задать в pad-to
>
 
> --gap-fill val --pad-to val
>

Это ваще не в тему.

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

13. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 10-Ноя-14, 03:48 
> Это ваще не в тему.

Подтверждаю. Как я и говорил, я не уверен на 100% что в objdump будет нужная функция, просто помнил, что с помощью её выдирал секции из объектников, вот и сказал посмотреть в ту сторону.

Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

11. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 10-Ноя-14, 03:38 
> Подскажите , а как с помощью этого ключа правильно определить смещение сегмента
> данных чтобы задать в 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".
В этой цепочке я изменял асм полученный из сырца, а не из объектника. Ваша задача понять, как получить из объектника такой асм файл, чтобы он мог быть скомпилирован обратно в объектник. Остальная процедура будет такая же, как у меня.

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

12. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 10-Ноя-14, 03:46 
Нет, похоже никак не выйдет скомпилировать выхлоп objdump. Так что этот способ тоже не подходит. Вообще странное задание, кому может понадобиться изменять размер секции .data? Как вообще можно изменить её размер, разве что новых данных туда добавить, только они же не будут использованы кодом программы, короче бессмысленное задание немного. И вообще, какая тема? Линкер, системные утилиты, работа с асмом? Т.е. что предполагается должно быть использовано для решения задачи?
Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

9. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от pavlinux (ok) on 10-Ноя-14, 03:05 
> чтобы уменьшился размер сегмента данных

1. Ну изначально было "Изменить размер сегмента данных в объектном файле",
поэтому извиняйте, выбрал в сторону увеличения, как имеющее какой-то смысл. :D
2. Куда девать данные из .data? (а их можно много куда засунуть, в оверлей например).
3. Насколько уменьшать?

> А на сколько я понимаю линковщик создаст уже исполняемый файлы.

Можно и не линковать: ld -T script.ld -r old.o -o new.o  

В общем копипасть оригинал задания.  

Ну и последнее,я учебному заданию предшествуют лекции в которых все должно быть описано.
Сдаётся мне, что это задание при устройстве на работу.

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

14. "Изменить размер сегмента данных объектного файла"  +1 +/
Сообщение от skb7 (ok) on 10-Ноя-14, 03:59 
В общем, я сделал, как 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

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

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

15. "Изменить размер сегмента данных объектного файла"  +/
Сообщение от CROSP (ok) on 10-Ноя-14, 22:31 
>[оверквотинг удален]
> 3. Перепаковуем линкером используя свой скрипт линкера:
>
 
> $ ld -T custom.ld -r main.o -o main2.o
>

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

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

Спасибо Вам огромное !! Все получилось , я был близок к Вашему решению. Только не смог найти ключа чтобы не собирать выполняемый файл (искать зависимости). Спасибо огромное еще раз.

Ответить | Правка | ^ к родителю #14 | Наверх | Cообщить модератору

16. "Изменить размер сегмента данных объектного файла"  +/
Сообщение от skb7 (ok) on 11-Ноя-14, 00:37 
> Спасибо Вам огромное !! Все получилось , я был близок к Вашему
> решению. Только не смог найти ключа чтобы не собирать выполняемый файл
> (искать зависимости). Спасибо огромное еще раз.

Не за что. Я тоже не знал такой опции, pavlinux подсказал.

Ответить | Правка | ^ к родителю #15 | Наверх | Cообщить модератору

17. "Изменить размер сегмента данных объектного файла"  +/
Сообщение от Fend2015 (ok) on 13-Дек-14, 14:23 
$ cat data.c
char data[1024*1024]={0};
int main(){return 0;}
$ gcc -fno-zero-initialized-in-bss -c data.c
$ objdump -h data.o | grep -A1 \\.data
  1 .data         00100000  0000000000000000  0000000000000000  00000080  2**6
                  CONTENTS, ALLOC, LOAD, DATA


Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




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

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