[Arm] Fix parsing and emission of Tag_also_compatible_with eabi attribute
According to the ABI for the Arm Architecture, the value for the
Tag_also_compatible_with eabi attribute is represented by an NTBS entry.
This string value, in turn, is composed of a pair of tag+value encoded
in one of two formats:
- ULEB128: tag, ULEB128: value, 0.
- ULEB128: tag, NBTS: data.
(See [[ 60a8eb8c55/addenda32/addenda32.rst (3373secondary-compatibility-tag)
| section 3.3.7.3 on the Addenda to, and Errata in, the ABI for the Arm Architecture ]].)
Currently the Arm assembly parser and streamer ignore the encoding of
the attribute's NTBS value, which can result in incorrect attributes
being emitted in both assembly and object file outputs.
This patch fixes these issues by properly handing the value's encoding.
An update to llvm-readobj to properly handle the attribute's value will be
covered by a separate patch.
Patch by Victor Campos and Lucas Prates.
Reviewed By: vhscampos
Differential Revision: https://reviews.llvm.org/D129500
This commit is contained in:
parent
f96e159321
commit
ba9caf9170
|
@ -263,6 +263,8 @@ enum {
|
|||
PACRETUsed = 1
|
||||
};
|
||||
|
||||
std::string encodeAttrTagValuePair(StringRef OriginalString);
|
||||
|
||||
} // namespace ARMBuildAttrs
|
||||
} // namespace llvm
|
||||
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/ARMBuildAttributes.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -71,3 +76,39 @@ constexpr TagNameMap ARMAttributeTags{tagData};
|
|||
const TagNameMap &llvm::ARMBuildAttrs::getARMAttributeTags() {
|
||||
return ARMAttributeTags;
|
||||
}
|
||||
|
||||
static std::string getEncodedULEB128AsText(const uint8_t *Value,
|
||||
unsigned Size) {
|
||||
std::stringstream SS;
|
||||
for (unsigned i = 0; i < Size; ++i) {
|
||||
SS << "\\" << std::setfill('0') << std::setw(3) << std::oct
|
||||
<< int(Value[i]);
|
||||
}
|
||||
return SS.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
llvm::ARMBuildAttrs::encodeAttrTagValuePair(StringRef OriginalString) {
|
||||
auto BytesBegin = reinterpret_cast<const uint8_t *>(OriginalString.data());
|
||||
auto BytesEnd = BytesBegin + OriginalString.size();
|
||||
|
||||
unsigned N = 0;
|
||||
const char *Error = nullptr;
|
||||
unsigned Tag = decodeULEB128(BytesBegin, &N, BytesEnd, &Error);
|
||||
if (Error)
|
||||
report_fatal_error("Could not decode Tag value: " + Twine(Error));
|
||||
|
||||
std::string EncodedPair = getEncodedULEB128AsText(BytesBegin, N);
|
||||
switch (Tag) {
|
||||
case ARMBuildAttrs::CPU_raw_name:
|
||||
case ARMBuildAttrs::CPU_name:
|
||||
case ARMBuildAttrs::compatibility:
|
||||
case ARMBuildAttrs::conformance:
|
||||
EncodedPair += OriginalString.substr(N);
|
||||
break;
|
||||
default:
|
||||
EncodedPair +=
|
||||
getEncodedULEB128AsText(BytesBegin + N, OriginalString.size() - N);
|
||||
}
|
||||
return EncodedPair;
|
||||
}
|
||||
|
|
|
@ -11439,12 +11439,20 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string EscapedValue;
|
||||
if (IsStringValue) {
|
||||
if (Parser.getTok().isNot(AsmToken::String))
|
||||
return Error(Parser.getTok().getLoc(), "bad string constant");
|
||||
|
||||
StringValue = Parser.getTok().getStringContents();
|
||||
Parser.Lex();
|
||||
if (Tag == ARMBuildAttrs::also_compatible_with) {
|
||||
if (Parser.parseEscapedString(EscapedValue))
|
||||
return Error(Parser.getTok().getLoc(), "bad escaped string constant");
|
||||
|
||||
StringValue = EscapedValue;
|
||||
} else {
|
||||
StringValue = Parser.getTok().getStringContents();
|
||||
Parser.Lex();
|
||||
}
|
||||
}
|
||||
|
||||
if (Parser.parseEOL())
|
||||
|
|
|
@ -202,7 +202,12 @@ void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
|
|||
OS << "\t.cpu\t" << String.lower();
|
||||
break;
|
||||
default:
|
||||
OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
|
||||
OS << "\t.eabi_attribute\t" << Attribute << ", \"";
|
||||
if (Attribute == ARMBuildAttrs::also_compatible_with)
|
||||
OS << ARMBuildAttrs::encodeAttrTagValuePair(String);
|
||||
else
|
||||
OS << String;
|
||||
OS << "\"";
|
||||
if (IsVerboseAsm) {
|
||||
StringRef Name = ELFAttrs::attrTypeAsString(
|
||||
Attribute, ARMBuildAttrs::getARMAttributeTags());
|
||||
|
|
|
@ -63,6 +63,9 @@
|
|||
// Tag_BTI_extension (=52)
|
||||
.eabi_attribute 52, 0
|
||||
|
||||
// Tag_also_compatible_with (=65)
|
||||
.eabi_attribute 65, "\006\017"
|
||||
|
||||
// Tag_BTI_use (=74)
|
||||
.eabi_attribute 74, 0
|
||||
|
||||
|
@ -86,16 +89,16 @@
|
|||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x34
|
||||
// CHECK-NEXT: Size: 81
|
||||
// CHECK-NEXT: Size: 85
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
// CHECK-NEXT: AddressAlignment: 1
|
||||
// CHECK-NEXT: EntrySize: 0
|
||||
// CHECK-NEXT: SectionData (
|
||||
// CHECK-NEXT: 0000: 41500000 00616561 62690001 46000000 |AP...aeabi..F...|
|
||||
// CHECK-NEXT: 0000: 41540000 00616561 62690001 4A000000 |AT...aeabi..J...|
|
||||
// CHECK-NEXT: 0010: 05636F72 7465782D 61380006 0A074108 |.cortex-a8....A.|
|
||||
// CHECK-NEXT: 0020: 0109020A 030C0214 01150117 01180119 |................|
|
||||
// CHECK-NEXT: 0030: 011B001C 0124012A 012C022E 01320034 |.....$.*.,...2.4|
|
||||
// CHECK-NEXT: 0040: 0044034A 004C006E A0018101 3100FA01 |.D.J.L.n....1...|
|
||||
// CHECK-NEXT: 0050: 01 |.|
|
||||
// CHECK-NEXT: 0040: 0041060F 0044034A 004C006E A0018101 |.A...D.J.L.n....|
|
||||
// CHECK-NEXT: 0050: 3100FA01 01 |1....|
|
||||
// CHECK-NEXT: )
|
||||
|
|
|
@ -233,11 +233,14 @@
|
|||
@ CHECK-OBJ-NEXT: Value: 0
|
||||
@ CHECK-OBJ-NEXT: TagName: nodefaults
|
||||
@ CHECK-OBJ-NEXT: Description: Unspecified Tags UNDEFINED
|
||||
.eabi_attribute Tag_also_compatible_with, "gnu"
|
||||
@ CHECK: .eabi_attribute 65, "gnu"
|
||||
.eabi_attribute Tag_also_compatible_with, "\006\017"
|
||||
@ The value for Tag_also_compatible_with should be a pair of a tag (ULEB128) +
|
||||
@ a value (ULEB128 + null or NTBS). llvm-readobj doesn't now how to process
|
||||
@ this yet, so we use the encoded value explicitly here.
|
||||
@ CHECK: .eabi_attribute 65, "\006\017"
|
||||
@ CHECK-OBJ: Tag: 65
|
||||
@ CHECK-OBJ-NEXT: TagName: also_compatible_with
|
||||
@ CHECK-OBJ-NEXT: Value: gnu
|
||||
@ CHECK-OBJ-NEXT: Value:
|
||||
.eabi_attribute Tag_T2EE_use, 0
|
||||
@ CHECK: .eabi_attribute 66, 0
|
||||
@ CHECK-OBJ: Tag: 66
|
||||
|
|
Loading…
Reference in New Issue