Переписывание MSAmStmt с помощью segfaults плагина llvmC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Переписывание MSAmStmt с помощью segfaults плагина llvm

Сообщение Anonymous »

У меня есть код на C:

Код: Выделить всё

#include 
#include 

uint8_t count1(uint32_t x) {
int out;
__asm {
mov edx, [x]
mov al, 0
next:   cmp edx, 0
je done
mov cl, dl
and cl, 1
add al, cl
shr edx, 1
jmp next
done:
mov out, al
}
return out;
}

int main() {
uint32_t x = 0x5789ABCD;
uint8_t cnt = count1(x);
printf("Number of 1s in 0x%X: %hhu\n", x, cnt);
}
Я хочу написать плагин для LLVM, который незаметно преобразует его во что-то вроде этого:

Код: Выделить всё

#include 
#include 

uint8_t count1(uint32_t x) {
int out;
__asm {
.file 1 "main.c"
.loc 1 7
mov edx, [x]
.loc 1 8
mov al, 0
.loc 1 9
next:   cmp edx, 0
.loc 1 10
je done
.loc 1 11
mov cl, dl
.loc 1 12
and cl, 1
.loc 1 13
add al, cl
.loc 1 14
shr edx, 1
.loc 1 15
jmp next
done:
.loc 1 17
mov out, al
}
return out;
}

int main() {
uint32_t x = 0x5789ABCD;
uint8_t cnt = count1(x);
printf("Number of 1s in 0x%X: %hhu\n", x, cnt);
}
Это позволит мне подписать пошаговую отладку через блок __asm. Обратите внимание, что номера строк увеличиваются только на 1. Это сделано намеренно, поскольку, если плагин изменяет AST, номера строк в исходном файле не изменятся.
Я написал плагин, который может обнаружить этот оператор, я могу скомпилировать его и скомпилировать эту программу с clang и включенным этим плагином.
Но когда я пытаюсь вызвать Rewriter.ReplaceText(SourceRange(StartLoc, EndLoc), ModifiedAsm ); плагин выдает ошибку.
Я пробовал проверить, действительны ли диапазоны (они есть). Я попытался проверить, не являются ли они результатом расширения макроса (isMacroId() возвращает 0).
Я сузил его до Rewriter.getRangeSize(..) функция. Но я понятия не имею, что делаю не так.
Это соответствующая часть плагина:

Код: Выделить всё

class MyASTVisitor : public RecursiveASTVisitor {
public:
explicit MyASTVisitor(ASTContext *Context, Rewriter &R)
: Context(Context), TheRewriter(R) {}

bool VisitStmt(Stmt *S) {
if (auto *Asm = dyn_cast(S)) {
// Get the assembly string
StringRef AsmString = Asm->getAsmString();

SourceLocation StartLoc = Asm->getBeginLoc();
SourceLocation EndLoc = Asm->getEndLoc();

// This will segfault
bool result = TheRewriter.ReplaceText(SourceRange(StartLoc, EndLoc),
AsmString);
llvm::errs() 

Подробнее здесь: [url]https://stackoverflow.com/questions/79084233/rewriting-msasmstmt-with-llvm-plugin-segfaults[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

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

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»