Отметка времени переопределения библиотеки `ar`
Заголовок формата архива.a требует отметки времени. Это привело к бесчисленным головным болям, когда я перестраивал статическую библиотеку, главным образом потому, что я не могу точно воспроизвести исходный двоичный файл.
Например (это на моем Mac, но то же самое происходит в Linux x64):
$ cat foo.h
int foo();
$ cat foo.c
#include "foo.h"
int foo() { return 3; }
$ gcc -fno-pic -m64 -arch x86_64 -I/usr/local/include -O3 -c foo.c -o foo.o -fpic
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 0d0e6606185de4e994c47f4a0e54c1c4
$ mv libfoo.a libfoo.a1
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 22a69d42e1325ae8f978c2a18a4886da
Чтобы доказать себе, что единственной разницей было время, я взял diff на основе hexdump:
$ diff <(hexdump libfoo.a) <(hexdump libfoo.a1)
2,3c2,3
< 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 33 30
< 0000020 38 36 20 20 35 30 31 20 20 20 32 30 20 20 20 20
---
> 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 32 38
> 0000020 37 31 20 20 35 30 31 20 20 20 32 30 20 20 20 20
который, если вы выполняете обратное преобразование с использованием формата заголовка, соответствует полю времени.
Manpage не указывает, возможно ли переопределить метку времени из заголовка. Какие-нибудь мысли?
Изменить: да, можно вернуться и физически взломать файл, чтобы использовать произвольную метку времени. да, можно изменить поведение программы. Принимая во внимание обстоятельства, связанные с ситуацией, не все из которых носят сугубо технический характер, инструмент для ручного изменения метки времени не является приемлемым, а также модифицированная версия ar
и не влияет на текущее системное время.
Изменить: В этом случае я должен доказать, что без каких-либо недопустимых отклонений от пути сборки, двоичные файлы могут быть получены из источника. В некоторых отраслях (например, в сфере финансов) это, по-видимому, стандартная практика. Инструмент с ручным управлением для изменения меток времени недопустим (потому что использовался специальный инструмент, которого не было в исходном пути сборки). Ручная версия ar
недопустимо (похожая проблема). Проблема с изменением системных часов заключается в том, что сборка должна быть идеально скоординирована (это часовая сборка с большим количеством библиотек и двоичных файлов). Приемлемые решения включают в себя:
- флаги для AR или других программ, которые могут переопределить метку времени в библиотеке
- существующий (возраст> 1 года) инструмент для этого
- флаги GCC, которые могут переопределять метку времени, приходящую от ar, когда выполняется связывание
5 ответов
Если остальная часть двоичного файла всегда одинакова, вы можете найти метку времени в .a
файл и переопределить его с фиксированным значением (как и все нули).
Используйте "детерминированный режим" в ар. Смотрите опцию "D" для ar в руководстве.
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be libfoo.a
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be libfoo.a
Если вы используете ranlib
после этого убедитесь, что вы используете ranlib -D
; иначе ranlib
вернет отметку времени.
Использование dd позволит вам перезаписать ту часть файла, которую вы хотите:
dd if=libfoo.a1 of=libfoo.a skip=30 seek=30 count=4 bs=1 conv=notrunc
конечно, это означает, что вам понадобится ваша временная метка где-то еще (у вас может быть очень простая программа на с, которая берет текущее время и выводит его с прямым или прямым порядком байтов, а затем с помощью dd вы можете перезаписать файл библиотеки). используя dd, я могу перезаписать файл.a и не получить результатов сравнения
Я написал скрипт Python в своем GitHub для сброса временных меток для более старых версийar
у которого не было-D
вариант.
Я тестировал Python 3.8.10 и Python 2.6.6.
https://gist.github.com/Supermanuu/ccdbe0c5d15d41dd1df75ad288e2a30a
Используйте пример для очистки временных меток:
./manageStaticLibTimestamp.py cw *.a
Использование:
Usage: ./manageStaticLibTimestamp.py [pcw] <static library paths ...>
p - print timestamps
c - clear timestamps
w - write timestamps
Ответ по умолчанию: "Это не может быть сделано инструментом ar"