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

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

ru
Offline Offline

« : 08-10-2016 16:14 » 

Доброго времени суток.

Подскажите, как можно дописать линковочный скрипт так, что бы
объектный файл располагался по определенному адресу?

Код:
например: out.obj
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 08-10-2016 18:46 » 

Слишком мало информации.
Записан

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

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #2 : 09-10-2016 07:46 » 

RXL, дело в том, что весь код состоит из программных модулей.
А1.с А1.h ;    B1.c,  B2.h  .......  и  так далее.
Занимаются этими модулями разные люди.
после компиляции получаются объектные файлы
A1.obj  B1.obj  ..... и тд

Линкер собирает их в одну программу.
Вот можно, как-то в ликорвочном скрипте жестко  указать адрес расположения объектных файлов А1 и В1?
они будит идти друг за другом.
Я учту размер этих модулей, так что бы они не пересекались.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 09-10-2016 16:00 » 

zuuuuk, Важная информация это среда разработки! Например в связке GCC+Makefile такое делается на раз и два. Просто прописываются относительные пути.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #4 : 10-10-2016 06:45 » 

Finch,  процессор ARM. компилятор gcc.
Вы могли бы пример привести. или ссылку дать, что почитать.
как указать адрес расположения объектного файла?
вот
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #5 : 10-10-2016 10:14 » 

Строгих правил нет. У меня, к примеру, список объектных файлов задан OBJECT.
Типовой пример с поиском исходников:

Код: (GNU make)
    SOURCES=$(shell find . -name *.cpp)
    OBJECTS=$(SOURCES:%.cpp=%.o)

    all: $(OBJECTS)

    %.o: %.cpp
         <command to compile dependencies $< into target $@ >  $< -o  $@

Если makefile создается конфигуратором, то прямое его редактирование не имеет смысла и нужно смотреть опции конфигуратора.
« Последнее редактирование: 10-10-2016 10:21 от RXL » Записан

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

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #6 : 10-10-2016 14:19 » 

RXL, Это Makefile.
у меня другой вопрос.
как задать адрес расположения объектного файла?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #7 : 10-10-2016 15:57 » 

Вот такой Makefile я использую. Его еше нужно допиливать. Но
Код: (GNU make)
NAME=biado
#TESTNAME=test
_OBJ = main.o node.o Document.o
#_TESTOBJ = test.o mathaction.o functionaction.o Lexem.o Calculate.o Operator.o Value.o
DEPS =

CPP=g++
_OBJDIR=./obj/
_DISTDIR=./dist/

OBJ = $(patsubst %,$(OBJDIR)%,$(_OBJ))
#TESTOBJ = $(patsubst %,$(OBJDIR)%,$(_TESTOBJ))

ifeq ($(MAKECMDGOALS) , release)
CPPFLAG=-O2 -std=c++11
GOALDIR=release/
GOAL=$(DISTDIR)$(NAME)
LIBRARY=
else
CPPFLAG=-g -Wall -std=c++11
GOALDIR=debug/
GOAL = $(DISTDIR)$(NAME)
#$(DISTDIR)$(TESTNAME)
LIBRARY=  
endif

OBJDIR = $(_OBJDIR)$(GOALDIR)
DISTDIR = $(_DISTDIR)$(GOALDIR)

.PHONY: all
all: $(GOAL)

$(DISTDIR)$(NAME) : $(OBJ) | $(DISTDIR)
        $(CPP) $^ -o $@ $(CPPFLAG) $(LIBRARY)

#$(DISTDIR)$(TESTNAME) : $(TESTOBJ) | $(DISTDIR)
#       $(CPP) $^ -o $@ $(CPPFLAG) $(LIBRARY)

$(OBJDIR)%.o: %.cpp $(DEPS) | $(OBJDIR)
        $(CPP) -c $< -o $@ $(CPPFLAG) $(LIBRARY)
       
$(OBJDIR) :
        if [ ! -d $(_OBJDIR) ] ; then \
        mkdir $(_OBJDIR);\
        fi
        mkdir $(OBJDIR)

$(DISTDIR) :
        if [ ! -d $(_DISTDIR) ] ; then \
        mkdir $(_DISTDIR);\
        fi
        mkdir $(DISTDIR)

.PHONY: clean release

release:  $(DISTDIR)$(NAME)

clean:
        for x in $(_OBJDIR)* ; do rm -f $$x/*; done
        for x in $(_DISTDIR)* ; do rm -f $$x/*; done
       

Если в твоем проекте собираются также тесты, нужно разкоментировать соответствуюшие строчки.
« Последнее редактирование: 10-10-2016 16:01 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Aether
Молодой специалист

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

« Ответ #8 : 10-10-2016 16:35 » 

Вот такой Makefile я использую. Его еше нужно допиливать. Но
Я его понял немного не так: объектные файлы содержат функции, и он хочет иметь возможность их размещать внутри исполняемого файла так, как хочет, а не как их соединяет линковщик.
Например, как сделать main строго первой или строго последней в main.exe?

Вот только зачем это нужно? А черт его знает...
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 10-10-2016 16:48 » 

А я понял, что он хочет объектные файлы создавать в отдельной директории. С возможностью собирать из этой директории. Мой вариант Makefile как раз это делает. И более того раскидывает также по разным версиям сборки (debug, release). Также и целевой файл.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #10 : 11-10-2016 07:12 » 

Aether, вы правы. Именно это я и имел ввиду.
Цитата
Вот только зачем это нужно? А черт его знает...
Они будут идти в том порядку который задам я.
И потом скопировать в другое место при исполнении.

makefile данную задачу не решает.
Записан
Aether
Молодой специалист

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

« Ответ #11 : 11-10-2016 07:40 » 

И потом скопировать в другое место при исполнении.
Это как? Линковщик не просто соединяет объектные файлы в один, суть статического объединения в один исполняемый файл в том, что ссылки на функции прописываются жёстко, и отделить какую-то функцию, перенести её - невозможно, тут же нарушатся связи. Или это особенность ARM архитектуры?
В случае необходимости разделения программы и библиотеки существуют другие подходы - создание динамических библиотек, с таблицами виртуальных методов - DLL, COM... Тут нужно смотреть в сторону целевой ОС, если конечно, Вы не пишете собственную ОС?
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #12 : 11-10-2016 09:24 » 

GNU ld объединяет объектные файлы в порядке заданном командной строкой, включая библиотеки.
ld -static -o target main.o -lc boot.o ...
Разрешение символов происходит в том же порядке: если символ уже разрешен, но есть в следующей либе, то из либы он не импортируется.
« Последнее редактирование: 11-10-2016 09:27 от RXL » Записан

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

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #13 : 11-10-2016 11:53 » 

Я тоже как-то не понял, о чём вопрос. Если всё-таки об ld-скриптах GNU LD, то они позволяют задавать адреса, по которым будут располагаться те или иные секции, например так:

Код:
OUTPUT_ARCH(i386)
ENTRY(_entry)
{ . = 0x83010000;
  .text : {
    *(.text*)
    *(.rodata*)
    *(.rdata)
    . = ALIGN (4K);
  } = 0xcccccccc
  .data : {
    *(.data)
  }
  .bss . : {
    *(.bss)
  }
  .eh_frame (NOLOAD) : {
    *(.eh_frame)
  } :NONE
  /DISCARD/ : {
    *(.rdata$zzz)
  }
  . = ALIGN (0x1000);
}

По-видимому функции, которые надо будет размещать по строго фиксированным адресам, надо будет располагать в разных секциях (если не путаю, то это возможно при помощи атрибутов) - каждый в своей, а затем в ld-скрипте указывать по каким адресам располагается каждая из секций. Это всё надо пробовать - у меня именно такой задачи не стояло - насколько это всё работоспособно и как оно должно быть описано надо будет разбираться.
« Последнее редактирование: 11-10-2016 12:02 от darkelf » Записан
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #14 : 13-10-2016 07:27 » 

По-видимому функции, которые надо будет размещать по строго фиксированным адресам, надо будет располагать в разных секциях

Я нашёл как размещать функции по адресам. Спасибо.
А вот можно именно программный модуль (объектный файл) разместить в заданном адресе?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #15 : 13-10-2016 10:28 » 

По-видимому функции, которые надо будет размещать по строго фиксированным адресам, надо будет располагать в разных секциях
Я нашёл как размещать функции по адресам. Спасибо.
Вы-бы тогда привели своё решение, вдруг кому-то ещё понадобится - поищет он по форуму, найдёт Ваш вариант, и скажет Вам спасибо.

А вот можно именно программный модуль (объектный файл) разместить в заданном адресе?
В объектном файле могут быть как минимум секции кода и данных. По современным понятиям код должен быть защищен от записи, а данные - могут быть защищены (константные данные, не изменяемые строки и т.д.) или не защищены (глобальные переменные) от изменения, а кроме того ещё и защищены от выполнения. При линковке все секции кода из объектных файлов собираются в одну исполняемую секцию .text, все секции неизменяемых данных - в секцию .rodata, а все изменяемые - в секцию .data.

С учётом сказанного выше, не понятно, как для Вашего случая проводится защита, но Вы можете попробовать что-то типа такого:
Код:
OUTPUT_ARCH(i386)
ENTRY(_entry)
{ . = 0x83010000;
  .text : {
    . = 0x83010000;
    module1.o(.text*)
    module1.o(.rodata*)
    module1.o(.rdata*)
    module1.o(.data*)
    . = 0x83020000;
    module2.o(.text*)
    module2.o(.rodata*)
    module2.o(.rdata*)
    module2.o(.data*)
    . = ALIGN (4K);
  } = 0xcccccccc
  .bss . : {
    *(.bss)
  }
  .eh_frame (NOLOAD) : {
    *(.eh_frame)
  } :NONE
  /DISCARD/ : {
    *(.rdata$zzz)
  }
  . = ALIGN (0x1000);
}
Надо, конечно, проверять, но запись типа objectfile.o(.section) официально заявлена в документации и должна работать.
« Последнее редактирование: 13-10-2016 11:15 от darkelf » Записан
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #16 : 13-10-2016 11:22 » 

darkelf, Огромное спасибо. Я это и искал.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines