2013-08-01 1 views
0

У меня есть двоичный модуль ядра Linux для некоторых периферийных устройств. Он отлично работает, но использует профилирование, которое поддерживает я удалял из ядро ​​по соображениям производительности. Я не могу перекомпилировать модуль , потому что его стороннее проприетарное программное обеспечение и у меня нет доступа к исходному коду. Я только обладаю объектными файлами (* .o), необходимыми для , чтобы связать драйвер с моей версией ядра Linux.Удалить ссылки на __gnu_mcount_nc из предварительно скомпилированного модуля ядра Linux

Возможно ли обработать файл .ko и удалить прыжки на __gnu_mcount_nc функция? Я подумывал изменить код операции от bl <__gnu_mcount_nc> до mov r8,r8, но его трудно достичь из-за фактом, что каждая ветвь для внешней функции имеет ebfffffe код операции. Это привело меня к теме переселения, которую я хочу избежать. Я ищу для некоторого тривиального решения.

Disassembly of section .text: 

00000000 <some_func1>: 
     0:  e92d4000  push {lr} 
     4:  ebfffffe  bl  18e0 <__gnu_mcount_nc> 
     8:  e3a00001  mov  r0, #1 
     c:  e12fff1e  bx  lr 

00000010 <some_func2>: 
     10:  e92d4000  push {lr} 
     14:  ebfffffe  bl  18e0 <__gnu_mcount_nc> 
     18:  e3a00001  mov  r0, #1 
     1c:  e12fff1e  bx  lr 

00000020 <some_func3>: 
     20:  e92d4038  push {r3, r4, r5, lr} 
     24:  e92d4000  push {lr} 
     28:  ebfffffe  bl  18e0 <__gnu_mcount_nc> 
     2c:  e1a04001  mov  r4, r1 
     30:  e59f3038  ldr  r3, [pc, #56] ; 70 <some_func3+0x50> 
     34:  e5905034  ldr  r5, [r0, #52] ; 0x34 
... 

Целевая панель основана на armv7-архитектуре и ядре Cortex-A9.

Edit:

Вопрос 1:__mcount_loc содержит относительные указатели на <__gnu_mcount_nc>. Как известно ядро ​​при исправлении адресов, в каком разделе указатель относится к этому?

Вопрос 2: Кажется, что «взломанный» модуль ядра не работает. Выдача insmod .ko сообщение об ошибке запуска:

insmod: не может вставить «some_driver.ko»: неизвестный символ в модуле или недопустимый параметр

Должен ли я удалить символ __gnu_mcount_nc от некоторых раздел? Даже если его сейчас не использовать?

Ищете некоторые идеи, спасибо.

+0

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

+0

Извините, но я не понимаю. Я знаю, какие символы используются в модуле, и я хочу сохранить их все, кроме профилирования: __gnu_mcount_nc –

+0

Если вы выполните 'objdump -r <имя_of_object_file>' в командной строке, вы увидите список всех перемещений. В основном, когда модуль загружен, ядро ​​сканирует список переместителей и заменяет все эти команды 'ebfffffe' перескакиванием на фактические функции. Идея заключается в том, что вы сами можете сами просмотреть перемещение, чтобы найти что-нибудь, что относится к '__gnu_mcount_nc', и удалить эти записи перемещений (вам также потребуется изменить инструкцию, которую он называет« nop »или эквивалент). –

ответ

0

Вы должны перекомпилировать ядро ​​с поддержкой FTRACE и включить CONFIG_DYNAMIC_FTRACE.

Вам не нужно беспокоиться об этом, влияя на производительность - если трассировка фактически не включена, все вызовы __gnu_mcount_ncwill be NOPped out загрузчиком ядра. Это то, что раздел __mcount_loc (в финале .ko) для - он имеет список всех местоположений вызовов bl __gnu_mcount_nc в двоичном формате.

+0

Я сказал «причина производительности», но у меня также был размер самого ядра на моем уме - его примерно ** 170 кБ ** меньше без поддержки FTRACE. У меня очень ограниченная флеш-память, и мне бы хотелось, чтобы FTRACE был отключен. Итак, я остался с концепцией, чтобы изменить все 'BL <__ gnu_mcount_nc>' на '" mov r8, r8 "'. Я взял все относительные указатели на '__gnu_mcount_nc' из' __mcount_loc' и заменил инструкции. Это удалось - по крайней мере, из того, что я вижу после разборки модуля ядра. –

Смежные вопросы