Merge llvm, clang, compiler-rt, libc++, lld and lldb release_40 branch
r294123, and update build glue.
This commit is contained in:
commit
899ca3d65f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang400-import/; revision=313300
@ -17,6 +17,8 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <__undef_min_max>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
#pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
@ -8123,9 +8123,12 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// More folding opportunities when target permits.
|
// More folding opportunities when target permits.
|
||||||
if ((AllowFusion || HasFMAD) && Aggressive) {
|
if (Aggressive) {
|
||||||
// fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y (fma u, v, z))
|
// fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y (fma u, v, z))
|
||||||
if (N0.getOpcode() == PreferredFusedOpcode &&
|
// FIXME: The UnsafeAlgebra flag should be propagated to FMA/FMAD, but FMF
|
||||||
|
// are currently only supported on binary nodes.
|
||||||
|
if (Options.UnsafeFPMath &&
|
||||||
|
N0.getOpcode() == PreferredFusedOpcode &&
|
||||||
N0.getOperand(2).getOpcode() == ISD::FMUL &&
|
N0.getOperand(2).getOpcode() == ISD::FMUL &&
|
||||||
N0->hasOneUse() && N0.getOperand(2)->hasOneUse()) {
|
N0->hasOneUse() && N0.getOperand(2)->hasOneUse()) {
|
||||||
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
||||||
@ -8137,7 +8140,10 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fold (fadd x, (fma y, z, (fmul u, v)) -> (fma y, z (fma u, v, x))
|
// fold (fadd x, (fma y, z, (fmul u, v)) -> (fma y, z (fma u, v, x))
|
||||||
if (N1->getOpcode() == PreferredFusedOpcode &&
|
// FIXME: The UnsafeAlgebra flag should be propagated to FMA/FMAD, but FMF
|
||||||
|
// are currently only supported on binary nodes.
|
||||||
|
if (Options.UnsafeFPMath &&
|
||||||
|
N1->getOpcode() == PreferredFusedOpcode &&
|
||||||
N1.getOperand(2).getOpcode() == ISD::FMUL &&
|
N1.getOperand(2).getOpcode() == ISD::FMUL &&
|
||||||
N1->hasOneUse() && N1.getOperand(2)->hasOneUse()) {
|
N1->hasOneUse() && N1.getOperand(2)->hasOneUse()) {
|
||||||
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
||||||
@ -8367,10 +8373,13 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// More folding opportunities when target permits.
|
// More folding opportunities when target permits.
|
||||||
if ((AllowFusion || HasFMAD) && Aggressive) {
|
if (Aggressive) {
|
||||||
// fold (fsub (fma x, y, (fmul u, v)), z)
|
// fold (fsub (fma x, y, (fmul u, v)), z)
|
||||||
// -> (fma x, y (fma u, v, (fneg z)))
|
// -> (fma x, y (fma u, v, (fneg z)))
|
||||||
if (N0.getOpcode() == PreferredFusedOpcode &&
|
// FIXME: The UnsafeAlgebra flag should be propagated to FMA/FMAD, but FMF
|
||||||
|
// are currently only supported on binary nodes.
|
||||||
|
if (Options.UnsafeFPMath &&
|
||||||
|
N0.getOpcode() == PreferredFusedOpcode &&
|
||||||
N0.getOperand(2).getOpcode() == ISD::FMUL &&
|
N0.getOperand(2).getOpcode() == ISD::FMUL &&
|
||||||
N0->hasOneUse() && N0.getOperand(2)->hasOneUse()) {
|
N0->hasOneUse() && N0.getOperand(2)->hasOneUse()) {
|
||||||
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
return DAG.getNode(PreferredFusedOpcode, SL, VT,
|
||||||
@ -8384,7 +8393,10 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
|
|||||||
|
|
||||||
// fold (fsub x, (fma y, z, (fmul u, v)))
|
// fold (fsub x, (fma y, z, (fmul u, v)))
|
||||||
// -> (fma (fneg y), z, (fma (fneg u), v, x))
|
// -> (fma (fneg y), z, (fma (fneg u), v, x))
|
||||||
if (N1.getOpcode() == PreferredFusedOpcode &&
|
// FIXME: The UnsafeAlgebra flag should be propagated to FMA/FMAD, but FMF
|
||||||
|
// are currently only supported on binary nodes.
|
||||||
|
if (Options.UnsafeFPMath &&
|
||||||
|
N1.getOpcode() == PreferredFusedOpcode &&
|
||||||
N1.getOperand(2).getOpcode() == ISD::FMUL) {
|
N1.getOperand(2).getOpcode() == ISD::FMUL) {
|
||||||
SDValue N20 = N1.getOperand(2).getOperand(0);
|
SDValue N20 = N1.getOperand(2).getOperand(0);
|
||||||
SDValue N21 = N1.getOperand(2).getOperand(1);
|
SDValue N21 = N1.getOperand(2).getOperand(1);
|
||||||
|
@ -4039,11 +4039,6 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
|||||||
Constant *CMinus1 = ConstantInt::get(Op0->getType(), *CmpC - 1);
|
Constant *CMinus1 = ConstantInt::get(Op0->getType(), *CmpC - 1);
|
||||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, CMinus1);
|
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, CMinus1);
|
||||||
}
|
}
|
||||||
// (x <u 2147483648) -> (x >s -1) -> true if sign bit clear
|
|
||||||
if (CmpC->isMinSignedValue()) {
|
|
||||||
Constant *AllOnes = Constant::getAllOnesValue(Op0->getType());
|
|
||||||
return new ICmpInst(ICmpInst::ICMP_SGT, Op0, AllOnes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4063,11 +4058,6 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
|||||||
if (*CmpC == Op0Max - 1)
|
if (*CmpC == Op0Max - 1)
|
||||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0,
|
return new ICmpInst(ICmpInst::ICMP_EQ, Op0,
|
||||||
ConstantInt::get(Op1->getType(), *CmpC + 1));
|
ConstantInt::get(Op1->getType(), *CmpC + 1));
|
||||||
|
|
||||||
// (x >u 2147483647) -> (x <s 0) -> true if sign bit set
|
|
||||||
if (CmpC->isMaxSignedValue())
|
|
||||||
return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
|
|
||||||
Constant::getNullValue(Op0->getType()));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4299,6 +4289,27 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
|||||||
(SI->getOperand(2) == Op0 && SI->getOperand(1) == Op1))
|
(SI->getOperand(2) == Op0 && SI->getOperand(1) == Op1))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// FIXME: We only do this after checking for min/max to prevent infinite
|
||||||
|
// looping caused by a reverse canonicalization of these patterns for min/max.
|
||||||
|
// FIXME: The organization of folds is a mess. These would naturally go into
|
||||||
|
// canonicalizeCmpWithConstant(), but we can't move all of the above folds
|
||||||
|
// down here after the min/max restriction.
|
||||||
|
ICmpInst::Predicate Pred = I.getPredicate();
|
||||||
|
const APInt *C;
|
||||||
|
if (match(Op1, m_APInt(C))) {
|
||||||
|
// For i32: x >u 2147483647 -> x <s 0 -> true if sign bit set
|
||||||
|
if (Pred == ICmpInst::ICMP_UGT && C->isMaxSignedValue()) {
|
||||||
|
Constant *Zero = Constant::getNullValue(Op0->getType());
|
||||||
|
return new ICmpInst(ICmpInst::ICMP_SLT, Op0, Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For i32: x <u 2147483648 -> x >s -1 -> true if sign bit clear
|
||||||
|
if (Pred == ICmpInst::ICMP_ULT && C->isMinSignedValue()) {
|
||||||
|
Constant *AllOnes = Constant::getAllOnesValue(Op0->getType());
|
||||||
|
return new ICmpInst(ICmpInst::ICMP_SGT, Op0, AllOnes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Instruction *Res = foldICmpInstWithConstant(I))
|
if (Instruction *Res = foldICmpInstWithConstant(I))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
|
@ -158,8 +158,9 @@ struct MemAccessTy {
|
|||||||
|
|
||||||
bool operator!=(MemAccessTy Other) const { return !(*this == Other); }
|
bool operator!=(MemAccessTy Other) const { return !(*this == Other); }
|
||||||
|
|
||||||
static MemAccessTy getUnknown(LLVMContext &Ctx) {
|
static MemAccessTy getUnknown(LLVMContext &Ctx,
|
||||||
return MemAccessTy(Type::getVoidTy(Ctx), UnknownAddressSpace);
|
unsigned AS = UnknownAddressSpace) {
|
||||||
|
return MemAccessTy(Type::getVoidTy(Ctx), AS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2279,8 +2280,10 @@ bool LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
|
|||||||
// TODO: Be less conservative when the type is similar and can use the same
|
// TODO: Be less conservative when the type is similar and can use the same
|
||||||
// addressing modes.
|
// addressing modes.
|
||||||
if (Kind == LSRUse::Address) {
|
if (Kind == LSRUse::Address) {
|
||||||
if (AccessTy != LU.AccessTy)
|
if (AccessTy.MemTy != LU.AccessTy.MemTy) {
|
||||||
NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->getContext());
|
NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->getContext(),
|
||||||
|
AccessTy.AddrSpace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conservatively assume HasBaseReg is true for now.
|
// Conservatively assume HasBaseReg is true for now.
|
||||||
|
@ -7190,14 +7190,6 @@ class TransformTypos : public TreeTransform<TransformTypos> {
|
|||||||
|
|
||||||
ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
|
ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
|
||||||
|
|
||||||
ExprResult TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
|
||||||
return Owned(E);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExprResult TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
|
||||||
return Owned(E);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExprResult Transform(Expr *E) {
|
ExprResult Transform(Expr *E) {
|
||||||
ExprResult Res;
|
ExprResult Res;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -2932,16 +2932,17 @@ class TreeTransform {
|
|||||||
ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
|
ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
|
||||||
SourceLocation IvarLoc,
|
SourceLocation IvarLoc,
|
||||||
bool IsArrow, bool IsFreeIvar) {
|
bool IsArrow, bool IsFreeIvar) {
|
||||||
// FIXME: We lose track of the IsFreeIvar bit.
|
|
||||||
CXXScopeSpec SS;
|
CXXScopeSpec SS;
|
||||||
DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
|
DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
|
||||||
return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
|
ExprResult Result = getSema().BuildMemberReferenceExpr(
|
||||||
/*FIXME:*/IvarLoc, IsArrow,
|
BaseArg, BaseArg->getType(),
|
||||||
SS, SourceLocation(),
|
/*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
|
||||||
/*FirstQualifierInScope=*/nullptr,
|
/*FirstQualifierInScope=*/nullptr, NameInfo,
|
||||||
NameInfo,
|
/*TemplateArgs=*/nullptr,
|
||||||
/*TemplateArgs=*/nullptr,
|
/*S=*/nullptr);
|
||||||
/*S=*/nullptr);
|
if (IsFreeIvar && Result.isUsable())
|
||||||
|
cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Build a new Objective-C property reference expression.
|
/// \brief Build a new Objective-C property reference expression.
|
||||||
|
@ -94,11 +94,18 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
|
|||||||
bool SuggestStatic = false;
|
bool SuggestStatic = false;
|
||||||
os << "Call to '" << FName << "' uses";
|
os << "Call to '" << FName << "' uses";
|
||||||
if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
|
if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
|
||||||
|
const VarDecl *VD = VR->getDecl();
|
||||||
|
// FIXME: These should have correct memory space and thus should be filtered
|
||||||
|
// out earlier. This branch only fires when we're looking from a block,
|
||||||
|
// which we analyze as a top-level declaration, onto a static local
|
||||||
|
// in a function that contains the block.
|
||||||
|
if (VD->isStaticLocal())
|
||||||
|
return;
|
||||||
// We filtered out globals earlier, so it must be a local variable
|
// We filtered out globals earlier, so it must be a local variable
|
||||||
// or a block variable which is under UnknownSpaceRegion.
|
// or a block variable which is under UnknownSpaceRegion.
|
||||||
if (VR != R)
|
if (VR != R)
|
||||||
os << " memory within";
|
os << " memory within";
|
||||||
if (VR->getDecl()->hasAttr<BlocksAttr>())
|
if (VD->hasAttr<BlocksAttr>())
|
||||||
os << " the block variable '";
|
os << " the block variable '";
|
||||||
else
|
else
|
||||||
os << " the local variable '";
|
os << " the local variable '";
|
||||||
|
@ -816,9 +816,11 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
|
|||||||
|
|
||||||
const StackFrameContext *STC = V.get<const StackFrameContext*>();
|
const StackFrameContext *STC = V.get<const StackFrameContext*>();
|
||||||
|
|
||||||
if (!STC)
|
if (!STC) {
|
||||||
|
// FIXME: Assign a more sensible memory space to static locals
|
||||||
|
// we see from within blocks that we analyze as top-level declarations.
|
||||||
sReg = getUnknownRegion();
|
sReg = getUnknownRegion();
|
||||||
else {
|
} else {
|
||||||
if (D->hasLocalStorage()) {
|
if (D->hasLocalStorage()) {
|
||||||
sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
|
sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
|
||||||
? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
|
? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
|
||||||
|
@ -1849,6 +1849,8 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
|
|||||||
|
|
||||||
// Function-scoped static variables are default-initialized to 0; if they
|
// Function-scoped static variables are default-initialized to 0; if they
|
||||||
// have an initializer, it would have been processed by now.
|
// have an initializer, it would have been processed by now.
|
||||||
|
// FIXME: This is only true when we're starting analysis from main().
|
||||||
|
// We're losing a lot of coverage here.
|
||||||
if (isa<StaticGlobalSpaceRegion>(MS))
|
if (isa<StaticGlobalSpaceRegion>(MS))
|
||||||
return svalBuilder.makeZeroVal(T);
|
return svalBuilder.makeZeroVal(T);
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ struct Configuration {
|
|||||||
bool Bsymbolic;
|
bool Bsymbolic;
|
||||||
bool BsymbolicFunctions;
|
bool BsymbolicFunctions;
|
||||||
bool ColorDiagnostics = false;
|
bool ColorDiagnostics = false;
|
||||||
|
bool DefineCommon;
|
||||||
bool Demangle = true;
|
bool Demangle = true;
|
||||||
bool DisableVerify;
|
bool DisableVerify;
|
||||||
bool EhFrameHdr;
|
bool EhFrameHdr;
|
||||||
|
@ -496,6 +496,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||||||
Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false);
|
Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false);
|
||||||
Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
|
Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
|
||||||
Config->Relocatable = Args.hasArg(OPT_relocatable);
|
Config->Relocatable = Args.hasArg(OPT_relocatable);
|
||||||
|
Config->DefineCommon = getArg(Args, OPT_define_common, OPT_no_define_common,
|
||||||
|
!Config->Relocatable);
|
||||||
Config->Discard = getDiscardOption(Args);
|
Config->Discard = getDiscardOption(Args);
|
||||||
Config->SaveTemps = Args.hasArg(OPT_save_temps);
|
Config->SaveTemps = Args.hasArg(OPT_save_temps);
|
||||||
Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
|
Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
|
||||||
|
@ -45,6 +45,9 @@ def color_diagnostics: F<"color-diagnostics">,
|
|||||||
def color_diagnostics_eq: J<"color-diagnostics=">,
|
def color_diagnostics_eq: J<"color-diagnostics=">,
|
||||||
HelpText<"Use colors in diagnostics">;
|
HelpText<"Use colors in diagnostics">;
|
||||||
|
|
||||||
|
def define_common: F<"define-common">,
|
||||||
|
HelpText<"Assign space to common symbols">;
|
||||||
|
|
||||||
def disable_new_dtags: F<"disable-new-dtags">,
|
def disable_new_dtags: F<"disable-new-dtags">,
|
||||||
HelpText<"Disable new dynamic tags">;
|
HelpText<"Disable new dynamic tags">;
|
||||||
|
|
||||||
@ -130,6 +133,9 @@ def no_as_needed: F<"no-as-needed">,
|
|||||||
def no_color_diagnostics: F<"no-color-diagnostics">,
|
def no_color_diagnostics: F<"no-color-diagnostics">,
|
||||||
HelpText<"Do not use colors in diagnostics">;
|
HelpText<"Do not use colors in diagnostics">;
|
||||||
|
|
||||||
|
def no_define_common: F<"no-define-common">,
|
||||||
|
HelpText<"Do not assign space to common symbols">;
|
||||||
|
|
||||||
def no_demangle: F<"no-demangle">,
|
def no_demangle: F<"no-demangle">,
|
||||||
HelpText<"Do not demangle symbol names">;
|
HelpText<"Do not demangle symbol names">;
|
||||||
|
|
||||||
@ -255,6 +261,9 @@ def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>;
|
|||||||
def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>;
|
def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>;
|
||||||
def alias_Bstatic_static: F<"static">, Alias<Bstatic>;
|
def alias_Bstatic_static: F<"static">, Alias<Bstatic>;
|
||||||
def alias_L__library_path: J<"library-path=">, Alias<L>;
|
def alias_L__library_path: J<"library-path=">, Alias<L>;
|
||||||
|
def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>;
|
||||||
|
def alias_define_common_dc: F<"dc">, Alias<define_common>;
|
||||||
|
def alias_define_common_dp: F<"dp">, Alias<define_common>;
|
||||||
def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
|
def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
|
||||||
def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
|
def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
|
||||||
def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;
|
def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;
|
||||||
@ -320,7 +329,6 @@ def plugin_opt_eq: J<"plugin-opt=">;
|
|||||||
// Options listed below are silently ignored for now for compatibility.
|
// Options listed below are silently ignored for now for compatibility.
|
||||||
def allow_shlib_undefined: F<"allow-shlib-undefined">;
|
def allow_shlib_undefined: F<"allow-shlib-undefined">;
|
||||||
def cref: Flag<["--"], "cref">;
|
def cref: Flag<["--"], "cref">;
|
||||||
def define_common: F<"define-common">;
|
|
||||||
def demangle: F<"demangle">;
|
def demangle: F<"demangle">;
|
||||||
def detect_odr_violations: F<"detect-odr-violations">;
|
def detect_odr_violations: F<"detect-odr-violations">;
|
||||||
def g: Flag<["-"], "g">;
|
def g: Flag<["-"], "g">;
|
||||||
@ -347,9 +355,6 @@ def G: JoinedOrSeparate<["-"], "G">;
|
|||||||
def Qy : F<"Qy">;
|
def Qy : F<"Qy">;
|
||||||
|
|
||||||
// Aliases for ignored options
|
// Aliases for ignored options
|
||||||
def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>;
|
|
||||||
def alias_define_common_dc: F<"dc">, Alias<define_common>;
|
|
||||||
def alias_define_common_dp: F<"dp">, Alias<define_common>;
|
|
||||||
def alias_Map_eq: J<"Map=">, Alias<Map>;
|
def alias_Map_eq: J<"Map=">, Alias<Map>;
|
||||||
def alias_version_script_version_script: J<"version-script=">,
|
def alias_version_script_version_script: J<"version-script=">,
|
||||||
Alias<version_script>;
|
Alias<version_script>;
|
||||||
|
@ -73,6 +73,8 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
|
|||||||
return VA;
|
return VA;
|
||||||
}
|
}
|
||||||
case SymbolBody::DefinedCommonKind:
|
case SymbolBody::DefinedCommonKind:
|
||||||
|
if (!Config->DefineCommon)
|
||||||
|
return 0;
|
||||||
return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
|
return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
|
||||||
cast<DefinedCommon>(Body).Offset;
|
cast<DefinedCommon>(Body).Offset;
|
||||||
case SymbolBody::SharedKind: {
|
case SymbolBody::SharedKind: {
|
||||||
|
@ -59,6 +59,9 @@ template <class ELFT> InputSection<ELFT> *elf::createCommonSection() {
|
|||||||
ArrayRef<uint8_t>(), "COMMON");
|
ArrayRef<uint8_t>(), "COMMON");
|
||||||
Ret->Live = true;
|
Ret->Live = true;
|
||||||
|
|
||||||
|
if (!Config->DefineCommon)
|
||||||
|
return Ret;
|
||||||
|
|
||||||
// Sort the common symbols by alignment as an heuristic to pack them better.
|
// Sort the common symbols by alignment as an heuristic to pack them better.
|
||||||
std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
|
std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
|
||||||
std::stable_sort(Syms.begin(), Syms.end(),
|
std::stable_sort(Syms.begin(), Syms.end(),
|
||||||
@ -434,7 +437,7 @@ template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
MipsGotSection<ELFT>::MipsGotSection()
|
MipsGotSection<ELFT>::MipsGotSection()
|
||||||
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL,
|
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL,
|
||||||
SHT_PROGBITS, Target->GotEntrySize, ".got") {}
|
SHT_PROGBITS, 16, ".got") {}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
void MipsGotSection<ELFT>::addEntry(SymbolBody &Sym, uintX_t Addend,
|
void MipsGotSection<ELFT>::addEntry(SymbolBody &Sym, uintX_t Addend,
|
||||||
@ -1168,10 +1171,14 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
|
|||||||
ESym->setVisibility(Body->symbol()->Visibility);
|
ESym->setVisibility(Body->symbol()->Visibility);
|
||||||
ESym->st_value = Body->getVA<ELFT>();
|
ESym->st_value = Body->getVA<ELFT>();
|
||||||
|
|
||||||
if (const OutputSectionBase *OutSec = getOutputSection(Body))
|
if (const OutputSectionBase *OutSec = getOutputSection(Body)) {
|
||||||
ESym->st_shndx = OutSec->SectionIndex;
|
ESym->st_shndx = OutSec->SectionIndex;
|
||||||
else if (isa<DefinedRegular<ELFT>>(Body))
|
} else if (isa<DefinedRegular<ELFT>>(Body)) {
|
||||||
ESym->st_shndx = SHN_ABS;
|
ESym->st_shndx = SHN_ABS;
|
||||||
|
} else if (isa<DefinedCommon>(Body)) {
|
||||||
|
ESym->st_shndx = SHN_COMMON;
|
||||||
|
ESym->st_value = cast<DefinedCommon>(Body)->Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
if (Config->EMachine == EM_MIPS) {
|
if (Config->EMachine == EM_MIPS) {
|
||||||
// On MIPS we need to mark symbol which has a PLT entry and requires
|
// On MIPS we need to mark symbol which has a PLT entry and requires
|
||||||
@ -1203,6 +1210,8 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolBody::DefinedCommonKind:
|
case SymbolBody::DefinedCommonKind:
|
||||||
|
if (!Config->DefineCommon)
|
||||||
|
return nullptr;
|
||||||
return In<ELFT>::Common->OutSec;
|
return In<ELFT>::Common->OutSec;
|
||||||
case SymbolBody::SharedKind: {
|
case SymbolBody::SharedKind: {
|
||||||
auto &SS = cast<SharedSymbol<ELFT>>(*Sym);
|
auto &SS = cast<SharedSymbol<ELFT>>(*Sym);
|
||||||
|
@ -476,6 +476,16 @@ static int getPPC64SectionRank(StringRef SectionName) {
|
|||||||
.Default(1);
|
.Default(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All sections with SHF_MIPS_GPREL flag should be grouped together
|
||||||
|
// because data in these sections is addressable with a gp relative address.
|
||||||
|
static int getMipsSectionRank(const OutputSectionBase *S) {
|
||||||
|
if ((S->Flags & SHF_MIPS_GPREL) == 0)
|
||||||
|
return 0;
|
||||||
|
if (S->getName() == ".got")
|
||||||
|
return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
|
template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
|
||||||
if (!Config->ZRelro)
|
if (!Config->ZRelro)
|
||||||
return false;
|
return false;
|
||||||
@ -494,8 +504,6 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
|
|||||||
return true;
|
return true;
|
||||||
if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
|
if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
|
||||||
return true;
|
return true;
|
||||||
if (In<ELFT>::MipsGot && Sec == In<ELFT>::MipsGot->OutSec)
|
|
||||||
return true;
|
|
||||||
if (Sec == Out<ELFT>::BssRelRo)
|
if (Sec == Out<ELFT>::BssRelRo)
|
||||||
return true;
|
return true;
|
||||||
StringRef S = Sec->getName();
|
StringRef S = Sec->getName();
|
||||||
@ -595,6 +603,8 @@ static bool compareSectionsNonScript(const OutputSectionBase *A,
|
|||||||
if (Config->EMachine == EM_PPC64)
|
if (Config->EMachine == EM_PPC64)
|
||||||
return getPPC64SectionRank(A->getName()) <
|
return getPPC64SectionRank(A->getName()) <
|
||||||
getPPC64SectionRank(B->getName());
|
getPPC64SectionRank(B->getName());
|
||||||
|
if (Config->EMachine == EM_MIPS)
|
||||||
|
return getMipsSectionRank(A) < getMipsSectionRank(B);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
|
|||||||
case ELF::PT_GNU_EH_FRAME:
|
case ELF::PT_GNU_EH_FRAME:
|
||||||
outs() << "EH_FRAME ";
|
outs() << "EH_FRAME ";
|
||||||
break;
|
break;
|
||||||
|
case ELF::PT_GNU_RELRO:
|
||||||
|
outs() << " RELRO ";
|
||||||
|
break;
|
||||||
case ELF::PT_GNU_STACK:
|
case ELF::PT_GNU_STACK:
|
||||||
outs() << " STACK ";
|
outs() << " STACK ";
|
||||||
break;
|
break;
|
||||||
@ -45,6 +48,18 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
|
|||||||
case ELF::PT_LOAD:
|
case ELF::PT_LOAD:
|
||||||
outs() << " LOAD ";
|
outs() << " LOAD ";
|
||||||
break;
|
break;
|
||||||
|
case ELF::PT_NOTE:
|
||||||
|
outs() << " NOTE ";
|
||||||
|
break;
|
||||||
|
case ELF::PT_OPENBSD_BOOTDATA:
|
||||||
|
outs() << " OPENBSD_BOOTDATA ";
|
||||||
|
break;
|
||||||
|
case ELF::PT_OPENBSD_RANDOMIZE:
|
||||||
|
outs() << " OPENBSD_RANDOMIZE ";
|
||||||
|
break;
|
||||||
|
case ELF::PT_OPENBSD_WXNEEDED:
|
||||||
|
outs() << " OPENBSD_WXNEEDED ";
|
||||||
|
break;
|
||||||
case ELF::PT_PHDR:
|
case ELF::PT_PHDR:
|
||||||
outs() << " PHDR ";
|
outs() << " PHDR ";
|
||||||
break;
|
break;
|
||||||
|
@ -8,4 +8,4 @@
|
|||||||
|
|
||||||
#define CLANG_VENDOR "FreeBSD "
|
#define CLANG_VENDOR "FreeBSD "
|
||||||
|
|
||||||
#define SVN_REVISION "293807"
|
#define SVN_REVISION "294123"
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
#define LLD_VERSION_STRING "4.0.0"
|
#define LLD_VERSION_STRING "4.0.0"
|
||||||
#define LLD_VERSION_MAJOR 4
|
#define LLD_VERSION_MAJOR 4
|
||||||
#define LLD_VERSION_MINOR 0
|
#define LLD_VERSION_MINOR 0
|
||||||
#define LLD_REVISION_STRING "293807"
|
#define LLD_REVISION_STRING "294123"
|
||||||
#define LLD_REPOSITORY_STRING "FreeBSD"
|
#define LLD_REPOSITORY_STRING "FreeBSD"
|
||||||
|
Loading…
Reference in New Issue
Block a user