Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сборка программы в формате "a.out"  (Прочитано 22202 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« : 24-05-2007 10:26 » 

По умолчанию компоновщик "ld" формирует исполняемый файл в формате "elf32".
Подскажите, как мне собрать исполняемый файл в формате "a.out"?

Я собираю программу следующей командой:
Код:
gcc -o exe sourc.c
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 24-05-2007 11:18 » 

pinfo ld

--oformat FORMAT

Список доступных форматов: objdump -i
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 24-05-2007 11:34 » 

Передача параметра --oformat=a.out-i386-linux у меня приводит к тому, что линковщик начинает ругаться и прекрощает свою работу. Я пытался даже формировать выходной файл и через скрипт линкера (параметр: OUTPUT), но он также отказывается на выходе выдовать "a.out". Хотя команда "objdump -i" сообщает, что данный формат поддерживается.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 24-05-2007 12:37 » 

Я попробовал такой пример:
Код: (C)
#include <stdio.h>

int main()
{
    puts("test\n");
    return 0;
}

Собираю:
$ ld -o t1 t1.o --oformat=a.out-i386-linux
ld: warning: cannot find entry symbol _start; defaulting to 08048020
t1.o(.text+0x12): In function `main':
: undefined reference to `puts'
ld: t1: can not represent section `.comment' in a.out object file format
ld: final link failed: Nonrepresentable section on output


Проблемы:
1. Не найдена подходящая run-time библиотека.
2. Библиотека /usr/lib/libc.so не подходит для a.out.
3. Нет секции ".comment" и линкер не знает, куда девать информацию.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 24-05-2007 13:17 » 

Спосибо RXL, что пытаешся так же разобраться в этой проблеме.

Теперь по существу: первая и вторая проблемы в принцепе на данном этапе меня не волнуют. А вот проблема три стоит на моем пути.
Для сборки исполняемого файла использую вот такой исходник:
Код:
#include <config.h>

#define ABS(x)          (x-_start)

#define SELECTOR_CODE           8
#define SELECTOR_VIDEO         16

/* код для реального режима работы (i8086) */
.code16

.text
.globl _start

/*
 * Код загружается в память по адресу 7с00h,
 * в DL номер накопителя. Управления передается по
 * адресу 0:7с00h.
 * Это значит, что
 * CS = 0
 * IP = 7c00h
 * DL = номеру накопителя (в соответствии с правилами
 *      BIOS int 13h).
 *
 * Итого:
 * регистры:
 *  cs:ip - 0:7c00h
 *  dl    - номер накопителя
 * память:
 *  00000-003FF      таблица векторов прерываний
 *  00400-005FF      используется BIOS ( 1536 )
 *  00600-07BFF      свободно ( 30208 )
 *  07C00-07DFF      программа начальной загрузки ( 512 )
 *  07E00-9FFFF      свободно ( 623104 )
 *  A0000-FFFFF      используется BIOS ( 393216 )
 */

/* настроим рабочее пространство данный и стека */
_start:
jmp main

msg: .asciz "Kernel code starting...\n"

/* основной код программы */
main:
cli
movw $SEG_BOOT_KERNEL, %ax
movw %ax, %ds           /* определяем сегмент данных         */
sti

/* Сообщение о начале работы kernel */
movw $ABS(msg), %ax
pushw %ax
call puts
addw $2, %sp

cli
lgdtw _gdtr

/* Переключаемся в PM */
movl %cr0, %eax
orb $1, %al
movl %eax, %cr0

ljmp $SELECTOR_CODE, $entry_PM

.code32
entry_PM:
movw $SELECTOR_VIDEO, %ax
movw %ax, %ds

xorl %eax, %eax
movw $0x1f41, (%eax)

movl $3998, %eax
movw $0x1f41,(%eax)

stop: jmp stop

_gdtr:
.word 23
.long _gdt+0x8000
_gdt:
.quad 0x0000000000000000
.quad 0x00c09a0080000000
.quad 0x0040920b80000f9f
На счет разных режимов работы (".code16" и ".code32") не обращайте внимания, это инструкции только для ассемблера, а линкеру по барабанну какой код в секции ".text" 32 или 16 разрядный.
Скрипт для линкера имеет следующий вид:
Код:
OUTPUT_FORMAT ("binary")
OUTPUT_ARCH (i386)
ENTRY (_start)
SECTIONS
{
    .text :
    {
*(.text)
    }
    .bss :
    {
*(.bss)
    }
    .data :
    {
*(.data)
    }
}
Так вот, я хочу заменить выходной формат файла с "binary" на "a.out-i386-linux" но в объектных файлах выдоваемых "gcc" (точнее будет "as") пресутствует секция ".comment" и как мне от нее избавиться я не знаю. У кого есть подобный опыт работы, поделитесь своими познаниями, я буду очень признателен.

Причина по которой я хочу использовать именно формат "a.out" заключается в то, что он намного проще "elf32" и его проще разместить в памяти. Кроме этого, исполняемый файл собранный в формате "a.out" является, если так можно сказать, самодостаточным если он не использует системные вызовы.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 24-05-2007 13:31 » 

Ну, какие ты библиотеки подключаешь - я не знаю, но закомментировав include и call puts и олпределив SEG_BOOT_KERNEL мне удалось собрать.

$ ld -o t1 t1.o -nostdlib --oformat=a.out-i386-linux -T t1.ld

Секция .comment явно тянется за библиотеками. Нельзяли ее исключить вообще средствами того же скрипта линкера?

Попробуй разобраться:
pinfo ld
Scripts/SECTIONS/Output Section Discarding
« Последнее редактирование: 24-05-2007 13:39 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 24-05-2007 13:48 » 

Например если так:
Код:
OUTPUT_FORMAT ("binary")
OUTPUT_ARCH (i386)
ENTRY (_start)
SECTIONS
{
    .text :
    {
        *(.text)
    }

    .bss :
    {
        *(.bss)
    }

    .data :
    {
        *(.data)
    }

    /DISCARD/ :
    {
        *(.comment)
    }
}

Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 25-05-2007 04:25 » 

Ну, какие ты библиотеки подключаешь - я не знаю, но закомментировав include и call puts и олпределив SEG_BOOT_KERNEL мне удалось собрать.

$ ld -o t1 t1.o -nostdlib --oformat=a.out-i386-linux -T t1.ld
Мне кажется, что опция --oformat=a.out-i386-linux была просто проигнарированна, т.к. в t1.ld прописан выходной формат OUTPUT_FORMAT ("binary").

Я прикрепил рабочий проект, собирается make all. На моем linux-e при указании в файле ./kernel/kernel.lds параметра OUTPUT_FORMAT("a.out-i386-linux"), проект перестает собираться.

Кстати, библиотеки внешние ни какие не используются.

* file.tar.gz (5.01 Кб - загружено 1054 раз.)
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 25-05-2007 06:19 » 

Serg79, в kernel/kernel.lds добавь строку в список секций:
    /DISCARD/ : { *(.comment) }
И исправь OUTPUT_FORMAT.
У меня все собралось.
Версии: gcc - 3.3.3, binutils - 2.15.90.0.3, make - 3.80.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 25-05-2007 06:53 » 

Спасибо RXL, без тебя я бы на это еще много времени потратил бы.

Впринципе все вроде бы выходин нормально:
Код:
kernel:     file format a.out-i386-linux
kernel
architecture: i386, flags 0x000001bc:
HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, WP_TEXT, D_PAGED
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000f0  00001020  00001020  00000020  2**3
                  CONTENTS, ALLOC, LOAD, CODE
  1 .data         00001000  00002000  00002000  00000110  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00003000  00003000  00000000  2**3
                  ALLOC
SYMBOL TABLE:
000000c8 g       .text 0000 00 05 putchar
00000080 g       .text 0000 00 05 put
000000a4 g       .text 0000 00 05 puts
00000000 g       .text 0000 00 05 _start
Размещение секций определим уже как будет удобно. Дома буду копать дальше.

Мне вот только одно не нравиться, что то большой файл получается на выходе, у меня аж 4444 байта получилось.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 25-05-2007 07:54 » 

Просто секция .data на размер страницы - файл почти весь из нулей состоит. Используй ключ -n для ld.
Также я бы удалил символы - добавь ключ -s в параметры ld.
Итог - 272 байта.
« Последнее редактирование: 25-05-2007 07:56 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 28-05-2007 04:12 » 

Просто секция .data на размер страницы - файл почти весь из нулей состоит. Используй ключ -n для ld.
Также я бы удалил символы - добавь ключ -s в параметры ld.
Итог - 272 байта.
Огромный респект тебе RXL.
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 28-05-2007 04:43 » 

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

У меня еще такой вопрос остался, я так понимаю: в секцию ".text" ложиться весь код и на нее можно накладывать свойство чтение и исполнение, в секцию ".data" помещаются все проинициализированные константные данные такие как ("const int i = 0x1234; const char msg[] = "Hello world"; fopen("~/file","r"); и т.д.") и на нее можно накладывать свойство только чтение, в секцию ".data" помещаются все глобальные переменные ("int a; char buff[256]; и т.д.") и на нее можно накладывать свойство чтение и запись, стек лучше распологать на вершине адресного пространства и накладывать свойство чтение запись, расширяется в низ. А все пространнство между секциями и стеком остаются для динамического выделения памяти.

Я так понимаю, что это стандартное распределение памяти для приложений.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 28-05-2007 06:13 » 

Примерно так.

В секции .data все инициализированные данные, кроме помещенных в секцию кода. Данные не делятся на только для чтения и полный доступ - формат a.out слишком прост для этого.

Еще в .bss располагаются неинициализированные данные. Секция физически отсутствует - заданы лишь смещение и размер в заголовке.

Только какая тебе разница, какие свойства секций, если ты будешь грузить это в RM...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 28-05-2007 06:41 » 

На данном этапе у меня в "RM" грузиться только boot который подгружает "kernel" в "HMA" переклучает в "PM" и передает управление "kernel". Сейчас у меня "kernel" полностью 32-разрядный.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines