Код: Выделить всё
#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);
}
Код: Выделить всё
#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);
}
Я написал плагин, который может обнаружить этот оператор, я могу скомпилировать его и скомпилировать эту программу с 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() 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]
Мобильная версия