C memcpy () функция

Вид hacky, но следующее должен работать:)

import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" user@myserver.com:"+serverPath)
5
задан caf 11 November 2009 в 21:09
поделиться

15 ответов

Мое предложение: не делайте этого.

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

0
ответ дан 18 December 2019 в 05:15
поделиться

Насколько я могу судить, исходный постер хочет сделать что-то, зависящее от реализации и поэтому не переносимое; это идет вразрез с тем, что стандарт C ++ говорит о приведении указателей к функциям, а не стандарт C, но здесь этого должно быть достаточно.

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

Все ссылки на потенциальные решения, похоже, используют поведение, зависящее от реализации, и я даже не уверен, что они делают то, что предполагалось сделать, но они могут быть подходит для ОП.

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

и очень непереносимый. И снова, это может не иметь значения для исходного плаката.

Все ссылки на потенциальные решения, похоже, используют поведение, зависящее от реализации, и я даже не уверен, что они делают то, что предполагалось сделать, но они могут быть подходит для ОП.

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

и очень непереносимый. И снова, это может не иметь значения для исходного плаката.

Все ссылки на потенциальные решения, похоже, используют поведение, зависящее от реализации, и я даже не уверен, что они делают то, что предполагалось, но они могут быть подходит для ОП.

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

Я даже не уверен, что они делают то, что предполагалось, но они могут подходить для ОП.

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

Я даже не уверен, что они делают то, что предполагалось, но они могут подходить для ОП.

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

0
ответ дан 18 December 2019 в 05:15
поделиться

Функция - это не просто объект, который можно скопировать. А как насчет перекрестных ссылок / символов и так далее? Конечно, вы можете взять что-то вроде стандартного пакета linux "binutils" и мучить свои двоичные файлы, но разве это то, что вы хотите?

Кстати, если вы просто пытаетесь заменить реализацию memcpy (), посмотрите вокруг механизма LD_PRELOAD.

0
ответ дан 18 December 2019 в 05:15
поделиться

Я могу придумать способ достичь того, чего вы хотите, но не скажу вам, потому что это ужасное злоупотребление языком.

0
ответ дан 18 December 2019 в 05:15
поделиться

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

0
ответ дан 18 December 2019 в 05:15
поделиться

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

Указатель на функцию может удовлетворить все это и является объектом первого класса. Указатель функции - это просто адрес памяти, и он обычно имеет такой же размер, как и любой другой указатель на вашем компьютере.

23
ответ дан 18 December 2019 в 05:15
поделиться

Используйте метод toInteger () для преобразования String в Integer , например,

int value = "99".toInteger()

Альтернативный вариант, который позволяет избежать использования устаревшего метода (см. ниже) -

int value = "66" as Integer

. Если вам нужно проверить, можно ли String преобразовать перед выполнением преобразования, используйте

String number = "66"

if (number.isInteger()) {
  int value = number as Integer
}

Grails

. преобразование параметра запроса в контроллер Grails, есть еще лучший способ

Integer paramValue = params.int('paramName')

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

Обновление устаревания

В последних версиях Groovy один из методов toInteger () объявлен устаревшим. Следующее взято из org.codehaus.groovy.runtime.

1
ответ дан 18 December 2019 в 05:15
поделиться

I don't quite understand what you are trying to accomplish, but assuming you compile with -fPIC and don't have your function do anything fancy, no other function calls, not accessing data from outside function, you might even get away with doing it once. I'd say the safest possibility is to limit the maximum size of supported function to, say, 1 kilobyte and just transfer that, and disregard the trailing junk.

If you really needed to know the exact size of a function, figure out your compiler's epilogue and prologue. This should look something like this on x86:

:your_func_epilogue
mov esp, ebp
pop ebp
ret
:end_of_func

;expect a varying length run of NOPs here

:next_func_prologue
push ebp
mov ebp, esp

Disassemble your compiler's output to check, and take the corresponding assembled sequences to search for. Epilogue alone might be enough, but all of this can bomb if searched sequence pops up too early, e.g. in the data embedded by the function. Searching for the next prologue might also get you into trouble, i think.

Now please ignore everything that i wrote, since you apparently are trying to approach the problem in the wrong and inherently unsafe way. Paint us a larger picture please, WHY are you trying to do that, and see whether we can figure out an entirely different approach.

3
ответ дан 18 December 2019 в 05:15
поделиться

Подобное обсуждение проводилось здесь:

http://www.motherboardpoint.com/getting-code-size-function-c-t95049.html

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

Если у вас GCC> = 4.4, вы можете попробовать отключить оптимизацию для своей функции, в частности, используя #pragma:

http: //gcc.gnu .org / on Lineledocs / gcc / Function-Specific-Option-Pragmas.html # Function-Specific-Option-Pragmas

Другое предложенное решение заключалось в том, чтобы вообще не копировать функцию, а определить функцию в том месте, где вы хотите скопировать на.

Удачи!

2
ответ дан 18 December 2019 в 05:15
поделиться

Вы хотите скопировать функцию? Я не думаю, что это возможно в C вообще. Предположим, у вас есть микроконтроллер Harvard-Architecture, где код (другими словами «функции») находится в ПЗУ. В этом случае вы вообще не можете этого сделать. Также я знаю несколько компиляторов и компоновщиков, которые оптимизируют файл (не только на уровне функций). В результате получается код операции, в котором части функций C. смешиваются друг с другом.

Единственный способ, который я считаю возможным, может быть:

  • Сгенерировать код операции вашей функции (например, путем компиляции / сборки ее самостоятельно).

  • Скопируйте этот код операции в массив C.

  • Используйте правильный указатель функции, указывающий на этот массив, для вызова этой функции.

  • Теперь вы можете выполнять все операции, общие для типичных «данных», с этим массивом .

Но помимо этого: рассматривали ли вы возможность изменения дизайна вашего программного обеспечения, чтобы вам не нужно было копировать содержимое функций?

3
ответ дан 18 December 2019 в 05:15
поделиться

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


Я собирался спросить, как операционные системы делают это, но теперь, когда я думаю об этом, когда ОС перемещает что-то вокруг нее, обычно перемещается целое page и обрабатывает память таким образом, что адреса переводятся в страницу / смещение. Я не уверен, что даже ОС когда-либо перемещает одну функцию в памяти.


Даже в случае, когда ОС перемещает функцию в памяти, сама функция должна быть объявлена ​​или иным образом скомпилирована / скомпилирована, чтобы разрешить такое действие, обычно через прагму, указывающую, что код можно перемещать. Все ссылки на память должны относиться к его собственному стековому кадру (также известному как локальные переменные) или включать какую-то структуру сегмент + смещение, чтобы ЦП, либо напрямую, либо по запросу ОС, мог выбрать соответствующее значение сегмента. Если в создании приложения участвовал компоновщик, приложение, возможно, придется повторно привязан к учетной записи для нового адреса функции.

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

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

5
ответ дан 18 December 2019 в 05:15
поделиться

It doesn't directly answer your question, but you should not implement call-backs from kernel code to user-space.

Injecting code into kernel-space is not a great work-around either.

It's better to represent the user/kernel barrier like a inter-process barrier. Pass data, not code, back and forth between a well defined protocol through a char device. If you really need to pass code, just wrap it up in a kernel module. You can then dynamically load/unload it, just like a .so-based plugin system.

On a side note, at first I misread that you did want to pass memcpy() to the kernel. You have to remind that it is a very special function. It is defined in the C standard, quite simple, and of a quite broad scope, so it is a perfect target to be provided as a built-in by the compiler.

Just like strlen(), strcmp() and others in GCC.

That said, the fact that is a built-in does not impede you ability to take a pointer to it.

8
ответ дан 18 December 2019 в 05:15
поделиться

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

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

Правильный подход заключается в том, чтобы ядро ​​делало некоторый дескриптор файла доступным для чтения после завершения асинхронного задания (в вашем случае этот дескриптор файла почти наверняка будет символьным устройством, предоставляемым вашим драйвером). Затем процесс пользовательского пространства может дождаться этого события с помощью select / poll или с помощью read - он может установить неблокирующий дескриптор файла, если хочет, и в основном просто используйте все стандартные инструменты UNIX для решения этого случая. В конце концов, именно так обрабатывается асинхронная природа сетевых сокетов (и почти все другие асинхронные случаи).

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

этот файловый дескриптор почти наверняка будет символьным устройством, предоставляемым вашим драйвером). Затем процесс пользовательского пространства может дождаться этого события с помощью select / poll или с помощью read - он может установить неблокирующий дескриптор файла, если хочет, и в основном просто используйте все стандартные инструменты UNIX для решения этого случая. В конце концов, именно так обрабатывается асинхронная природа сетевых сокетов (и почти все другие асинхронные случаи).

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

этот файловый дескриптор почти наверняка будет символьным устройством, предоставляемым вашим драйвером). Затем процесс пользовательского пространства может дождаться этого события с помощью select / poll или с помощью read - он может установить неблокирующий дескриптор файла, если хочет, и в основном просто используйте все стандартные инструменты UNIX для решения этого случая. В конце концов, именно так обрабатывается асинхронная природа сетевых сокетов (и почти все другие асинхронные случаи).

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

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

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

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

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

1
ответ дан 18 December 2019 в 05:15
поделиться

Я сделал это на Nintendo GBA, где я скопировал некоторые низкоуровневые функции рендеринга из флэш-памяти (16-битная память, медленная память) в высокоскоростную оперативную память рабочего пространства (32-битный доступ, по крайней мере, вдвое быстрее). Это было сделано путем взятия адреса функции сразу после функции, которую я хотел скопировать, size = (int) (NextFuncPtr - SourceFuncPtr). Это действительно сработало, но очевидно, что это не может быть гарантировано на всех платформах (точно не работает в Windows).

0
ответ дан 18 December 2019 в 05:15
поделиться

Я думаю, что одно из решений может быть таким, как показано ниже.

Например: если вы хотите чтобы знать размер функции func () в программе ac и иметь индикаторы до и после функции.

Попробуйте написать сценарий perl, который будет компилировать этот файл в объектный формат (cc -o), убедитесь, что операторы препроцессора не удалены . Они понадобятся вам позже, чтобы вычислить размер из объектного файла.

Теперь найдите два ваших индикатора и выясните размер кода между ними.

0
ответ дан 18 December 2019 в 05:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: