-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[MC] Fix clang integrated assembler generates incorrect relocations… #83115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
b7015a9
to
33a29c9
Compare
CurrentASMContent.take_front(NewlineIndex).take_back(SymbolLength); | ||
|
||
// Get and check if ".rdata" section exist. | ||
size_t RdataIndex = CurrentASMContent.find(".rdata"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GCC uses ".rodata.str1.4" for this code.
char *g = "xxxx";
char *x() {return g;}
Maybe the section name won't require to be something like ".rodata".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I think that we need a more generic solution.
The naive scan string may have lots of bug.
maybe something like, in the next lines, we may have:
do_read_rdata:
lw ...
lw ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, MipsAsmParser.cpp use following code to parse .rdata,so the name, maybe I think, basically it won’t change.
if (IDVal == ".rdata") {
parseRSectionDirective(".rodata");
return false;
}
And I have considered the situation you mentioned, the patch contains this situation, it use contains
to check if rdata section contains local symbol, instead of checking the next line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find
is not a good way here: you may meet some strange strings from user's asmcode, may be from comment?
# this is a comment about .rdata
// For O32, "$"-prefixed symbols are recognized as temporary while | ||
// .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L" | ||
// manually. | ||
if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L")) | ||
IsLocalSym = true; | ||
else { | ||
if (HasParseRdata == false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be
else if (HasParseRdata == false)
So we won't need 2-level nest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I would change it.
In fact we can update the generic asm scan for all ports, instead mips only. |
Can you explain it in more detail? |
size_t CommaIndex = CurrentASMContent.find_first_of(','); | ||
size_t SymbolLength = NewlineIndex - CommaIndex - 2; | ||
StringRef LocalSymbol = | ||
CurrentASMContent.take_front(NewlineIndex).take_back(SymbolLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the asm code is like
# more spaces and windows style newline
LA $a0, localsymbolname \r\n
It won't work.
CurrentASMContent.take_front(NewlineIndex).take_back(SymbolLength); | ||
|
||
// Get and check if ".rdata" section exist. | ||
size_t RdataIndex = CurrentASMContent.find(".rdata"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find
is not a good way here: you may meet some strange strings from user's asmcode, may be from comment?
# this is a comment about .rdata
Integrated assembler scan the asm code in That's the real problem, and this problem effects all architectures. |
OK,I would find another solution. |
@wzssyqa Please help review this patch yingopq@dcc86c6 |
…or mips32 Modify asm scan starting point to ensure scaning .rdata section before .text section. Save begin location, check if have .rdata section, confirm where to begin parse. If have it and .rdata after .text, begin parse from .rdata, when go to Eof, jump to begin location and then continue parse. If did not have .rdata or .rdata is before .text, jump to begin location and then parse. Fix llvm#65020
I guess that we can also CC @MaskRay |
@wzssyqa I tested with this patch about scaning twice, the result of diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 76a3e501f459..36c3f550e320 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -997,6 +997,9 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
getTargetParser().onBeginOfFile();
+ int cnt = 0;
+ SMLoc IDLoc_start = getTok().getLoc();
+A:
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
@@ -1017,6 +1020,13 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
eatToEndOfStatement();
}
+ cnt++;
+ if (cnt == 1) {
+ jumpToLoc(IDLoc_start);
+ Lex();
+ goto A;
+ }
+
getTargetParser().onEndOfFile();
printPendingErrors();
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 176d55aa890b..e6071abc02ed 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -42,7 +42,7 @@
#include <utility>
using namespace llvm;
-
+#define DEBUG_TYPE "mips-mcstreamer"
MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
S.setTargetStreamer(this);
}
@@ -424,9 +424,11 @@ void MCStreamer::assignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
Symbol->redefineIfPossible();
- if (!Symbol->isUndefined() || Symbol->isVariable())
- return getContext().reportError(Loc, "symbol '" + Twine(Symbol->getName()) +
- "' is already defined");
+ if (!Symbol->isUndefined() || Symbol->isVariable()) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE << "symbol '" + Twine(Symbol->getName()) +
+ "' is already defined" << "\n");
+ return;
+ }
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have more time spent on investigating the issue, but adding a lot of mips-specific code to the generic AsmParser.cpp is not acceptable.
Although her code is not correct, while I don't think that it is GNU GAS doesn't have this problem. |
@MaskRay Now we have two modification plans. |
… for mips32
When mips asm parse instruction la, check whether .rdata section was accessed and parsed, if it was not, then check the following statement, check if local symbol(eg "hello:") was in .rdata section, if it was in it, IsLocalSym is true.
Fix #65020