Проблемы с использованием инструкции LDR в сборке ARM

Я использую MacBook Pro M1.

Я пытаюсь загрузить значение, которое я поместил в сегмент .data в своем ассемблерном коде, но когда я смотрю на значение регистра с помощью LLDB, он показывает мне 0x0.

Вот код:

.global _main
.extern print
.extern printInt
.extern exit
.align 4
    
.text
_main:
    ldr x0, =num
    b exit
   
.data
num: .word 5

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

А вот регистр, считанный непосредственно перед выполнением инструкции LDR:

General Purpose Registers:
        x0 = 0x0000000000000001
        x1 = 0x000000016fdff2d0

А вот регистр, считанный сразу после выполнения инструкции LDR:

General Purpose Registers:
        x0 = 0x0000000000000000
        x1 = 0x000000016fdff2d0

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

Я попытался найти, что делает инструкция LDR, но веб-сайт ARM действительно неясен и сложен для обработки, а другие инструменты бесполезны. Я понятия не имею, что происходит половину времени.

ldr x0, =num должен загрузить адрес num, чего, скорее всего, нет 0x0000000000000001. Таким образом, вы, вероятно, допустили какую-то ошибку во время отладки. В любом случае, вам нужно нажать ldr x0, [x0], чтобы загрузить значение. Кроме того, .word является 32-битным, поэтому вы либо хотите использовать 32-битный регистр, либо .long
Jester 16.08.2024 21:12

@Jester Изменение с .word на .long практически не повлияло на код, а добавление ldc x0, [x0] дало мне EXC_BAD_ACCESS (code=1, address=0x0) или, в терминах неотладчика, segmentation fault, потому что я пытался получить доступ к 0x0.

Anirudh Mathur 16.08.2024 21:22

Вы не забыли связать объектный файл с двоичным файлом? Если да, то какую команду вы для этого набрали?

fuz 16.08.2024 22:05

@Jester: По словам Сигузы (Как загрузить данные по метке в Apple Silicon (ARM64)?), ldr x0, =num не работает на Darwin (потому что это расширится до чего-то, что включает перемещение текста, но __TEXT читается- только и динамический компоновщик не желает это обойти). И в ОП не упоминается запуск Linux на их MacBook. ИДК, возможно, что-то изменилось, поскольку ОП утверждает, что им удалось обойти это на шаг ldr.

Peter Cordes 17.08.2024 04:33

@PeterCordes По какой-то странной причине lldb не показывает мне раскрытие какой-либо инструкции, я получаю именно тот код, который написал. (Наверное, это какой-то дубляж)

Anirudh Mathur 17.08.2024 06:57

@PeterCordes Также я использую MacOS

Anirudh Mathur 17.08.2024 06:57

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

Peter Cordes 17.08.2024 23:37

Я обязательно попробую это!

Anirudh Mathur 18.08.2024 20:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это вина нового компоновщика Apple.

В течение долгого времени Apple использовала свой компоновщик ld64 для всех своих платформ. И в этом ответе я объясняю, почему использование ldr xN, =... не работает в macOS и что использовать вместо этого.

Я действительно думаю, что некоторые решения, сделанные в отношении внутренней работы конвейера LLVM Mach-O (в частности, в отношении перемещения сегментов), действительно затрудняют правильную поддержку этого принципа «выдать указатель и загрузить его на ПК». -relative-label» для целей Дарвина. Но конкретный способ проявления этой ошибки зависит от выбора, сделанного компоновщиком. В идеале компоновщик должен определить, что это проблема, и выдать ошибку во время компоновки. Но ld64, похоже, в блаженном неведении об ограничениях времени выполнения и просто выдает указатель на сегмент, где попытка перебазирования приведет к сбою процесса.

Но это было в прошлом году.

В Xcode 15 Apple объявила устаревшим ld64 и заменила его новым значением по умолчанию, которое я назвал dyld-ld из-за отсутствия лучшего имени.

Запуск what на этом новом ld или вызов его с помощью -v, используемого для идентификации его как части дерева исходного кода dyld еще в Xcode 15.0:

PROGRAM:ld  PROJECT:dyld-1015.7

Хотя, похоже, с тех пор он был выделен в отдельный проект:

PROGRAM:ld PROJECT:ld-1115.7.2

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

Теперь ld64 по-прежнему поставляется как ld-classic, и его можно выбрать в командной строке clang с помощью -ld_classic. Если вы скомпилируете свой код с этим, а затем запустите dyld_info -fixups на своем двоичном файле, вы увидите перезагрузку, которая должна быть применена (что приведет к сбою двоичного файла при запуске).

Если вы свяжетесь с dyld-ld (который можно явно выбрать с помощью -ld_new, хотя в любом случае это значение по умолчанию), то dyld_info -fixups вообще не будет показывать перебазирование для этого указателя. А если вы исследуете его в дизассемблере, то обнаружите, что оно просто имеет значение 0. Это означает, что такие бинарные файлы сейчас запустятся... но потом, скорее всего, просто вылетят из-за каких-то NULL указателей. И это то, что вы видите в lldb.

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

Мне надоела эта пустота без документации в программировании на ассемблере MacOS. Откуда ты, черт возьми, все это знаешь?? Есть ли у вас какие-либо ресурсы, которыми вы могли бы поделиться?

Anirudh Mathur 17.08.2024 14:44

Откуда я все это знаю? Что ж, я занимаюсь исследованиями безопасности на платформах Apple с конца 2016 года, а это просто требует глубокого погружения в суть вещей. И я де-факто сопровождаю джейлбрейк checkra1n, который по сложным причинам использует поддельный dyld во время загрузки, и первый раз я столкнулся с dyld-ld потому, что наш поддельный dyld перестал собираться с Xcode 15, и мне пришлось это сделать. потратьте день, работая над этим. Но ресурсы по этой теме... это сложный вопрос, потому что большая часть этих знаний собирается из крошечных кусочков на протяжении многих лет.

Siguza 17.08.2024 15:20

О кодировании я знаю, потому что много лет занимаюсь взломом ядра, поэтому для этого: исходный код XNU. Что касается dyld-ld: если у вас в какой-то момент есть свободный час, просмотрите /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeD‌​efault.xctoolchain/u‌​sr/bin/ и попытайтесь выяснить, что там делает каждый двоичный файл. Вам не нужно вникать в каждый из них, просто получите общее представление о том, что вообще включает в себя набор инструментов. Что касается ассемблерных причуд: комбинация clang -S, исходного кода LLVM, различных баз открытого исходного кода и, что не менее важно, просто компиляции вещей и последующего просмотра их в радаре2.

Siguza 17.08.2024 15:20

Также: часть о dyld-ld излучении NULL вместо указателя с возможностью перебазирования я узнал сегодня, потому что Питер Кордес прокомментировал ваш пост и задался вопросом, изменилось ли что-то, поэтому я написал небольшой фрагмент сборки, скомпилировал его и увидел, что его больше нет. произошел сбой при запуске, и затем я пошел выяснять, почему. Таким образом, это меньше «знания вещей» и больше «знания того, как разобраться в чем-то на лету», что… это просто навык, который вы приобретаете со временем, когда вы получаете более полное понимание всех различных частей системы, которую вы используете. работаем с.

Siguza 17.08.2024 15:31

Прохладный! Я воспользуюсь вашим советом и постараюсь следить за обновлениями компоновщика и молюсь богу, чтобы они это исправили. Часть меня хочет просто устроиться туда на работу и исправить все это самому.

Anirudh Mathur 17.08.2024 15:40

Другие вопросы по теме