2015-09-03 2 views
0

Справочная информация: Я рассматриваю разработку диспетчера пакетов, аналогичного портированию в Gentoo Linux (я могу закончить работу с портом). Для тех, кто мало знает о Gentoo, это дистрибутив, основанный на источнике, что означает, что все пакеты скомпилированы из исходного кода. В настоящее время можно скомпилировать программу в объектные файлы, а затем в исполняемые файлы.Можно ли удалить объектные файлы из исполняемого файла

$ gcc -c a.c -o a.o 
$ gcc -c b.c -o b.o 
$ gcc a.o b.o -o executable 

Улучшения, которые я хотел бы внести в portage, следующие.

  1. Возможность только повторной компиляции обновленных объектных файлов (изменение дорожек с использованием GIT или иным способом).
  2. Декомпилировать/Разблокировать исполняемые файлы объектов.
  3. Перекомпилируйте/переустановите объектные файлы, заменив только старые файлы объектов обновленными объектными файлами (Изменения отслеживаются с использованием GIT или иным образом).
  4. Затем вновь скомпилированный пакет заменяет старый пакет. (Тривиальная задача)

Рассуждение: Я пользователей Linux Arch, который любит идею распределения на основе источника, но не может быть беспокоили с огромной задачей держать свою систему в актуальном состоянии. Я также выполняю большую часть своей работы на портативном компьютере с небольшим жестким диском, поэтому причина декомпиляции/удаления ссылок на исполняемый файл с объектными файлами, а также просто хранение объектных файлов, занимающих большое пространство. Это также, вероятно, снизит общее время компиляции системы, поскольку необходимость перекомпиляции большей части исходного кода будет значительно уменьшена. Это также позволило бы легко изменить флаги USE на пакете без необходимости полной перекомпиляции.

Вопрос: Возможно ли скомпилировать объектные файлы в исполняемый файл и затем скомпилировать обратно в объектные файлы. Пример этого ниже.

$ gcc -c a.c -o a.o 
$ gcc -c b.c -o b.o 
$ gcc a.o b.o -o executable 

, а затем

$ SomeCommand executable 
output << a.o b.o 

Если это не возможно в настоящее время. Можно ли изменить версию компоновщика GNU «$ld» для регистрации изменений, которые он делает при связывании объектных файлов, чтобы сделать намеренно сделать программу «reverse Engineerable» ???

Редактировать: Другое использование для этого было бы слишком отдельным уникальным объектным файлом из исполняемого файла большого проекта для замены выделенного объектного файла на новый и повторной ссылки. Это уменьшит накладные расходы на перенаправление больших проектов из разных файлов, когда обновляется только один. Это позволит инкрементную компиляцию на двоичном уровне.

+0

Хм, возможно, вы можете создать собственный скрипт компоновщика, который хранит имена файлов .o и связывает его с разделами .text, .data и т. Д. Затем вы можете извлечь и заменить их 'elfsh' (http://www.eresi-project.org/wiki/TheELFsh). Как именно он мог работать, это не соответствует моим способностям, но^_^ –

+1

Как вы ожидаете восстановления из небольших исполняемых файлов .obj, которые (как вы сказали сами) довольно значительны? Я не думаю, что компоновщик сжимает исполняемый файл из-за какого-либо сжатия - он просто отбрасывает ненужную информацию. Поэтому, если вы должны включить в него вещи, необходимые для изменения процесса, размер исполняемого файла будет расти одинаково, что сделает весь процесс бесполезным. –

+0

Обычно вы теряете информацию при подключении. Во-первых, вы объединяете разделы каждого объектного файла в один и тот же раздел, превращая его в просто blob. Если вы этого не сделали, я полагаю, что можно было бы снова выполнить исполняемый файл (если вы знаете, какие разделы принадлежат к объективному файлу). – skyking

ответ

3

Нет, это невозможно. Большое количество работы компоновщика заменяет символические ссылки (действительные для любой комбинации объектных файлов, связанных друг с другом) с числовыми смещениями (действительными только для конкретного способа компоновщика, который решил выложить эту конкретную комбинацию объектных файлов, это конкретное время) , После того, как ссылки «запекаются» таким образом, они не могут быть восстановлены.

+0

У GNU ld есть опция' --emit-relocs', которая может заставить ее работать. Затем он мог попытаться отменить перемещение. Не уверен, что он работает для всех перемещений. –

+0

@ JohannesSchaub-litb Хорошая мысль, но с остальными разделами перемещения одна половина разумной мотивации для этого (уменьшение размера на диске) в значительной степени исчезнет. – Sneftel

+0

Но что, если эти данные хранились отдельно в отдельном файле (то есть в файле, который хранит численные смещения, которые заменяют символические ссылки). В основном то, что я ищу, - это способ сделать запись компоновщика тем, что она делает, и в этом случае изменения могут быть просто отменены ??? или я что-то упустил? – silvergasp

0

Это может быть осуществимо, если вы изменяете/настраиваете ld, чтобы сохранить разделы для каждого файла объекта отдельно, а также сохранить таблицу перемещения для каждого объектного файла в исполняемом файле.Также вы должны убедиться, что ld сохраняет имена объектных файлов в исполняемом файле, если вы хотите получить исходные имена файлов.

В основном линкер может просто соединяться с объектными файлами вместе, а затем выполнять перемещение, если перемещение обратимо, вы должны иметь возможность обратить вспять процесс.