|
28 | 28 | #include "clang/Basic/DarwinSDKInfo.h"
|
29 | 29 | #include "clang/Basic/IdentifierTable.h"
|
30 | 30 | #include "clang/Basic/LangOptions.h"
|
| 31 | +#include "clang/Basic/Linkage.h" |
31 | 32 | #include "clang/Basic/SourceLocation.h"
|
32 | 33 | #include "clang/Basic/SourceManager.h"
|
| 34 | +#include "clang/Basic/Specifiers.h" |
33 | 35 | #include "clang/Basic/TargetInfo.h"
|
34 | 36 | #include "clang/Lex/Preprocessor.h"
|
35 | 37 | #include "clang/Sema/Attr.h"
|
|
61 | 63 | #include "llvm/ADT/STLForwardCompat.h"
|
62 | 64 | #include "llvm/ADT/StringExtras.h"
|
63 | 65 | #include "llvm/Demangle/Demangle.h"
|
| 66 | +#include "llvm/IR/Attributes.h" |
64 | 67 | #include "llvm/IR/DerivedTypes.h"
|
65 | 68 | #include "llvm/MC/MCSectionMachO.h"
|
66 | 69 | #include "llvm/Support/Error.h"
|
@@ -2103,6 +2106,127 @@ static void handleCHERIMethodSuffix(Sema &S, Decl *D, const ParsedAttr &Attr) {
|
2103 | 2106 | D->addAttr(::new (S.Context) CHERIMethodSuffixAttr(S.Context, Attr, Str));
|
2104 | 2107 | }
|
2105 | 2108 |
|
| 2109 | +static void handleCHERIOTMMIODevice(Sema &S, Decl *D, const ParsedAttr &Attr, |
| 2110 | + Sema::DeclAttributeLocation DAL) { |
| 2111 | + auto *VD = dyn_cast<VarDecl>(D); |
| 2112 | + if (!VD || !VD->hasGlobalStorage()) |
| 2113 | + return; |
| 2114 | + |
| 2115 | + if (!VD->hasExternalStorage()) { |
| 2116 | + VD->setStorageClass(clang::SC_Extern); |
| 2117 | + } |
| 2118 | + |
| 2119 | + QualType QT = VD->getType(); |
| 2120 | + if (!QT.isVolatileQualified()) { |
| 2121 | + S.Diag(Attr.getLoc(), diag::warn_cheriot_global_cap_import_non_volatile) |
| 2122 | + << VD->getName() << Attr.getAttrName(); |
| 2123 | + } |
| 2124 | + |
| 2125 | + StringRef DeviceName; |
| 2126 | + SourceLocation DeviceNameLiteralLoc; |
| 2127 | + if (!S.checkStringLiteralArgumentAttr(Attr, 0, DeviceName, |
| 2128 | + &DeviceNameLiteralLoc)) |
| 2129 | + return; |
| 2130 | + StringRef Permissions; |
| 2131 | + SourceLocation PermissionsLiteralLoc; |
| 2132 | + |
| 2133 | + if (Attr.getNumArgs() > 1) { |
| 2134 | + S.checkStringLiteralArgumentAttr(Attr, 1, Permissions, |
| 2135 | + &PermissionsLiteralLoc); |
| 2136 | + } |
| 2137 | + |
| 2138 | + std::string OwnedPermissions = Permissions.str(); |
| 2139 | + |
| 2140 | + auto DuplicateSymbolCallback = [&Attr, &S, |
| 2141 | + Permissions](char DuplicateSymbol) { |
| 2142 | + S.Diag(Attr.getLoc(), diag::warn_cheriot_cap_permissions_duplicate_sym) |
| 2143 | + << Attr.getAttrName() << "'" + std::string({DuplicateSymbol}) + "'" |
| 2144 | + << Permissions; |
| 2145 | + }; |
| 2146 | + |
| 2147 | + auto ExtraneousSymbolCallback = [&Attr, &S, |
| 2148 | + Permissions](StringRef ExtraneousSymbols) { |
| 2149 | + S.Diag(Attr.getLoc(), |
| 2150 | + diag::err_cheriot_malformed_cap_permissions_unknown_sym) |
| 2151 | + << Attr.getAttrName() << ExtraneousSymbols << Permissions; |
| 2152 | + }; |
| 2153 | + |
| 2154 | + auto FailedSemanticCheckCallback = [&Attr, &S, |
| 2155 | + Permissions](StringRef Reason) { |
| 2156 | + S.Diag(Attr.getLoc(), |
| 2157 | + diag::err_cheriot_malformed_cap_permissions_invalid_dep) |
| 2158 | + << Attr.getAttrName() << Reason << Permissions; |
| 2159 | + }; |
| 2160 | + |
| 2161 | + if (!llvm::CHERIoTGlobalCapabilityImportAttr::checkPermissions( |
| 2162 | + OwnedPermissions, DuplicateSymbolCallback, ExtraneousSymbolCallback, |
| 2163 | + FailedSemanticCheckCallback)) |
| 2164 | + return; |
| 2165 | + |
| 2166 | + return D->addAttr(::new (S.Context) CHERIOTMMIODeviceAttr( |
| 2167 | + S.Context, Attr, DeviceName, OwnedPermissions)); |
| 2168 | +} |
| 2169 | + |
| 2170 | +static void handleCHERIOTSharedObject(Sema &S, Decl *D, const ParsedAttr &Attr, |
| 2171 | + Sema::DeclAttributeLocation DAL) { |
| 2172 | + auto *VD = dyn_cast<VarDecl>(D); |
| 2173 | + if (!VD || !VD->hasGlobalStorage()) |
| 2174 | + return; |
| 2175 | + |
| 2176 | + if (VD->hasInit()) { |
| 2177 | + S.Diag(Attr.getLoc(), diag::err_cheriot_global_cap_import_initialized) |
| 2178 | + << VD->getName() << Attr.getAttrName(); |
| 2179 | + } |
| 2180 | + |
| 2181 | + if (!VD->hasExternalStorage()) { |
| 2182 | + VD->setStorageClass(clang::SC_Extern); |
| 2183 | + } |
| 2184 | + |
| 2185 | + StringRef ObjectName; |
| 2186 | + SourceLocation ObjectNameLiteralLoc; |
| 2187 | + if (!S.checkStringLiteralArgumentAttr(Attr, 0, ObjectName, |
| 2188 | + &ObjectNameLiteralLoc)) |
| 2189 | + return; |
| 2190 | + StringRef Permissions; |
| 2191 | + SourceLocation PermissionsLiteralLoc; |
| 2192 | + |
| 2193 | + if (Attr.getNumArgs() > 1) { |
| 2194 | + S.checkStringLiteralArgumentAttr(Attr, 1, Permissions, |
| 2195 | + &PermissionsLiteralLoc); |
| 2196 | + } |
| 2197 | + |
| 2198 | + std::string OwnedPermissions = Permissions.str(); |
| 2199 | + |
| 2200 | + auto DuplicateSymbolCallback = [&Attr, &S, |
| 2201 | + Permissions](char DuplicateSymbol) { |
| 2202 | + S.Diag(Attr.getLoc(), diag::warn_cheriot_cap_permissions_duplicate_sym) |
| 2203 | + << Attr.getAttrName() << "'" + std::string({DuplicateSymbol}) + "'" |
| 2204 | + << Permissions; |
| 2205 | + }; |
| 2206 | + |
| 2207 | + auto ExtraneousSymbolCallback = [&Attr, &S, |
| 2208 | + Permissions](StringRef ExtraneousSymbols) { |
| 2209 | + S.Diag(Attr.getLoc(), |
| 2210 | + diag::err_cheriot_malformed_cap_permissions_unknown_sym) |
| 2211 | + << Attr.getAttrName() << ExtraneousSymbols << Permissions; |
| 2212 | + }; |
| 2213 | + |
| 2214 | + auto FailedSemanticCheckCallback = [&Attr, &S, |
| 2215 | + Permissions](StringRef Reason) { |
| 2216 | + S.Diag(Attr.getLoc(), |
| 2217 | + diag::err_cheriot_malformed_cap_permissions_invalid_dep) |
| 2218 | + << Attr.getAttrName() << Reason << Permissions; |
| 2219 | + }; |
| 2220 | + |
| 2221 | + if (!llvm::CHERIoTGlobalCapabilityImportAttr::checkPermissions( |
| 2222 | + OwnedPermissions, DuplicateSymbolCallback, ExtraneousSymbolCallback, |
| 2223 | + FailedSemanticCheckCallback)) |
| 2224 | + return; |
| 2225 | + |
| 2226 | + D->addAttr(::new (S.Context) CHERIOTSharedObjectAttr( |
| 2227 | + S.Context, Attr, ObjectName, OwnedPermissions)); |
| 2228 | +} |
| 2229 | + |
2106 | 2230 | static void handleCHERICompartmentName(Sema &S, Decl *D, const ParsedAttr &Attr,
|
2107 | 2231 | Sema::DeclAttributeLocation DAL) {
|
2108 | 2232 | // cheri_compartment is both:
|
@@ -7350,6 +7474,12 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
|
7350 | 7474 | case ParsedAttr::AT_CHERICompartmentName:
|
7351 | 7475 | handleCHERICompartmentName(S, D, AL, DAL);
|
7352 | 7476 | break;
|
| 7477 | + case ParsedAttr::AT_CHERIOTMMIODevice: |
| 7478 | + handleCHERIOTMMIODevice(S, D, AL, DAL); |
| 7479 | + break; |
| 7480 | + case ParsedAttr::AT_CHERIOTSharedObject: |
| 7481 | + handleCHERIOTSharedObject(S, D, AL, DAL); |
| 7482 | + break; |
7353 | 7483 | case ParsedAttr::AT_InterruptState:
|
7354 | 7484 | handleInterruptState(S, D, AL);
|
7355 | 7485 | break;
|
|
0 commit comments