cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
169 lines
5.4 KiB
C++
169 lines
5.4 KiB
C++
//===- MCAsmInfo.cpp - Asm Info -------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines target asm properties related what form asm statements
|
|
// should take.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/BinaryFormat/Dwarf.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/MC/MCValue.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
enum DefaultOnOff { Default, Enable, Disable };
|
|
}
|
|
static cl::opt<DefaultOnOff> DwarfExtendedLoc(
|
|
"dwarf-extended-loc", cl::Hidden,
|
|
cl::desc("Disable emission of the extended flags in .loc directives."),
|
|
cl::values(clEnumVal(Default, "Default for platform"),
|
|
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
|
|
cl::init(Default));
|
|
|
|
namespace llvm {
|
|
cl::opt<cl::boolOrDefault> UseLEB128Directives(
|
|
"use-leb128-directives", cl::Hidden,
|
|
cl::desc(
|
|
"Disable the usage of LEB128 directives, and generate .byte instead."),
|
|
cl::init(cl::BOU_UNSET));
|
|
}
|
|
|
|
MCAsmInfo::MCAsmInfo() {
|
|
SeparatorString = ";";
|
|
CommentString = "#";
|
|
LabelSuffix = ":";
|
|
PrivateGlobalPrefix = "L";
|
|
PrivateLabelPrefix = PrivateGlobalPrefix;
|
|
LinkerPrivateGlobalPrefix = "";
|
|
InlineAsmStart = "APP";
|
|
InlineAsmEnd = "NO_APP";
|
|
ZeroDirective = "\t.zero\t";
|
|
AsciiDirective = "\t.ascii\t";
|
|
AscizDirective = "\t.asciz\t";
|
|
Data8bitsDirective = "\t.byte\t";
|
|
Data16bitsDirective = "\t.short\t";
|
|
Data32bitsDirective = "\t.long\t";
|
|
Data64bitsDirective = "\t.quad\t";
|
|
GlobalDirective = "\t.globl\t";
|
|
WeakDirective = "\t.weak\t";
|
|
if (DwarfExtendedLoc != Default)
|
|
SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable;
|
|
if (UseLEB128Directives != cl::BOU_UNSET)
|
|
HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE;
|
|
UseIntegratedAssembler = true;
|
|
ParseInlineAsmUsingAsmParser = false;
|
|
PreserveAsmComments = true;
|
|
PPCUseFullRegisterNames = false;
|
|
}
|
|
|
|
MCAsmInfo::~MCAsmInfo() = default;
|
|
|
|
void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) {
|
|
InitialFrameState.push_back(Inst);
|
|
}
|
|
|
|
const MCExpr *
|
|
MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym,
|
|
unsigned Encoding,
|
|
MCStreamer &Streamer) const {
|
|
return getExprForFDESymbol(Sym, Encoding, Streamer);
|
|
}
|
|
|
|
const MCExpr *
|
|
MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
|
|
unsigned Encoding,
|
|
MCStreamer &Streamer) const {
|
|
if (!(Encoding & dwarf::DW_EH_PE_pcrel))
|
|
return MCSymbolRefExpr::create(Sym, Streamer.getContext());
|
|
|
|
MCContext &Context = Streamer.getContext();
|
|
const MCExpr *Res = MCSymbolRefExpr::create(Sym, Context);
|
|
MCSymbol *PCSym = Context.createTempSymbol();
|
|
Streamer.emitLabel(PCSym);
|
|
const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context);
|
|
return MCBinaryExpr::createSub(Res, PC, Context);
|
|
}
|
|
|
|
bool MCAsmInfo::isAcceptableChar(char C) const {
|
|
if (C == '@')
|
|
return doesAllowAtInName();
|
|
|
|
return isAlnum(C) || C == '_' || C == '$' || C == '.';
|
|
}
|
|
|
|
bool MCAsmInfo::isValidUnquotedName(StringRef Name) const {
|
|
if (Name.empty())
|
|
return false;
|
|
|
|
// If any of the characters in the string is an unacceptable character, force
|
|
// quotes.
|
|
for (char C : Name) {
|
|
if (!isAcceptableChar(C))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
|
|
// FIXME: Does .section .bss/.data/.text work everywhere??
|
|
return SectionName == ".text" || SectionName == ".data" ||
|
|
(SectionName == ".bss" && !usesELFSectionDirectiveForBSS());
|
|
}
|
|
|
|
void MCAsmInfo::initializeAtSpecifiers(ArrayRef<AtSpecifier> Descs) {
|
|
assert(AtSpecifierToName.empty() && "cannot initialize twice");
|
|
for (auto Desc : Descs) {
|
|
[[maybe_unused]] auto It =
|
|
AtSpecifierToName.try_emplace(Desc.Kind, Desc.Name);
|
|
assert(It.second && "duplicate Kind");
|
|
[[maybe_unused]] auto It2 =
|
|
NameToAtSpecifier.try_emplace(Desc.Name.lower(), Desc.Kind);
|
|
assert(It2.second);
|
|
}
|
|
}
|
|
|
|
StringRef MCAsmInfo::getSpecifierName(uint32_t S) const {
|
|
auto It = AtSpecifierToName.find(S);
|
|
assert(It != AtSpecifierToName.end() &&
|
|
"ensure the specifier is set in initializeVariantKinds");
|
|
return It->second;
|
|
}
|
|
|
|
std::optional<uint32_t> MCAsmInfo::getSpecifierForName(StringRef Name) const {
|
|
auto It = NameToAtSpecifier.find(Name.lower());
|
|
if (It != NameToAtSpecifier.end())
|
|
return It->second;
|
|
return {};
|
|
}
|
|
|
|
void MCAsmInfo::printExpr(raw_ostream &OS, const MCExpr &Expr) const {
|
|
if (auto *SE = dyn_cast<MCSpecifierExpr>(&Expr))
|
|
printSpecifierExpr(OS, *SE);
|
|
else
|
|
Expr.print(OS, this);
|
|
}
|
|
|
|
bool MCAsmInfo::evaluateAsRelocatableImpl(const MCSpecifierExpr &E,
|
|
MCValue &Res,
|
|
const MCAssembler *Asm) const {
|
|
if (!E.getSubExpr()->evaluateAsRelocatable(Res, Asm))
|
|
return false;
|
|
|
|
Res.setSpecifier(E.getSpecifier());
|
|
return !Res.getSubSym();
|
|
}
|