Skip to content

Commit 9d52298

Browse files
committed
Responding to Review Comments
Summary of changes: * Release Notes syntax fix * GcsReportPolicy has been reverted to an enum, with a function available for converting the value from an enum to string * getZGcsReport can now process both `-zgces-report` and `-zgcs-report-dynamic` at the same time, applying the values where the user has defined them, or the GNU Inheritance rules where appropriate * `elfPhdrs`, `numElfPhdrs` and `getElfPhdrs()` all removed as the information can be easily access from other locations.
1 parent 5a92afe commit 9d52298

File tree

5 files changed

+46
-60
lines changed

5 files changed

+46
-60
lines changed

lld/ELF/Config.h

+13-18
Original file line numberDiff line numberDiff line change
@@ -137,24 +137,7 @@ enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};
137137
enum class GcsPolicy { Implicit, Never, Always };
138138

139139
// For -z gcs-report= and -zgcs-report-dynamic
140-
struct GcsReportPolicy {
141-
enum Options { None, Warning, Error, Unknown } value;
142-
GcsReportPolicy(GcsReportPolicy::Options valueInput) : value(valueInput) {};
143-
144-
StringRef toString() {
145-
StringRef ret;
146-
if (value == Warning)
147-
ret = "warning";
148-
else if (value == Error)
149-
ret = "error";
150-
else
151-
ret = "none";
152-
153-
return ret;
154-
}
155-
156-
GcsReportPolicy::Options getValue() { return value; }
157-
};
140+
enum class GcsReportPolicy { None, Warning, Error, Unknown };
158141

159142
struct SymbolVersion {
160143
llvm::StringRef name;
@@ -767,6 +750,18 @@ uint64_t errCount(Ctx &ctx);
767750

768751
ELFSyncStream InternalErr(Ctx &ctx, const uint8_t *buf);
769752

753+
inline StringRef gcsReportPolicytoString(GcsReportPolicy value) {
754+
StringRef ret;
755+
if (value == GcsReportPolicy::Warning)
756+
ret = "warning";
757+
else if (value == GcsReportPolicy::Error)
758+
ret = "error";
759+
else
760+
ret = "none";
761+
762+
return ret;
763+
}
764+
770765
#define CHECK2(E, S) lld::check2((E), [&] { return toStr(ctx, S); })
771766

772767
} // namespace lld::elf

lld/ELF/Driver.cpp

+27-24
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ static void checkOptions(Ctx &ctx) {
400400
ErrAlways(ctx) << "-z bti-report only supported on AArch64";
401401
if (ctx.arg.zPauthReport != "none")
402402
ErrAlways(ctx) << "-z pauth-report only supported on AArch64";
403-
if (ctx.arg.zGcsReport.getValue() != GcsReportPolicy::None)
403+
if (ctx.arg.zGcsReport != GcsReportPolicy::None)
404404
ErrAlways(ctx) << "-z gcs-report only supported on AArch64";
405-
if (ctx.arg.zGcsReportDynamic.getValue() != GcsReportPolicy::None)
405+
if (ctx.arg.zGcsReportDynamic != GcsReportPolicy::None)
406406
ErrAlways(ctx) << "-z gcs-report-dynamic only supported on AArch64";
407407
if (ctx.arg.zGcs != GcsPolicy::Implicit)
408408
ErrAlways(ctx) << "-z gcs only supported on AArch64";
@@ -576,23 +576,27 @@ static GcsPolicy getZGcs(Ctx &ctx, opt::InputArgList &args) {
576576
return ret;
577577
}
578578

579-
static GcsReportPolicy
580-
getZGcsReport(Ctx &ctx, opt::InputArgList &args, bool isReportDynamic,
581-
GcsReportPolicy gcsReportValue = GcsReportPolicy::None) {
582-
GcsReportPolicy ret = GcsReportPolicy::None;
579+
static void getZGcsReport(Ctx &ctx, opt::InputArgList &args) {
580+
bool reportDynamicDefined = false;
583581

584582
for (auto *arg : args.filtered(OPT_z)) {
585583
std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
586-
if ((!isReportDynamic && kv.first == "gcs-report") ||
587-
(isReportDynamic && kv.first == "gcs-report-dynamic")) {
584+
if ((kv.first == "gcs-report") || kv.first == "gcs-report-dynamic") {
588585
arg->claim();
589-
ret = StringSwitch<GcsReportPolicy>(kv.second)
590-
.Case("none", GcsReportPolicy::None)
591-
.Case("warning", GcsReportPolicy::Warning)
592-
.Case("error", GcsReportPolicy::Error)
593-
.Default(GcsReportPolicy::Unknown);
594-
if (ret.getValue() == GcsReportPolicy::Unknown)
586+
GcsReportPolicy value = StringSwitch<GcsReportPolicy>(kv.second)
587+
.Case("none", GcsReportPolicy::None)
588+
.Case("warning", GcsReportPolicy::Warning)
589+
.Case("error", GcsReportPolicy::Error)
590+
.Default(GcsReportPolicy::Unknown);
591+
if (value == GcsReportPolicy::Unknown)
595592
ErrAlways(ctx) << "unknown -z " << kv.first << "= value: " << kv.second;
593+
594+
if (kv.first == "gcs-report")
595+
ctx.arg.zGcsReport = value;
596+
else if (kv.first == "gcs-report-dynamic") {
597+
ctx.arg.zGcsReportDynamic = value;
598+
reportDynamicDefined = true;
599+
}
596600
}
597601
}
598602

@@ -601,11 +605,9 @@ getZGcsReport(Ctx &ctx, opt::InputArgList &args, bool isReportDynamic,
601605
// inherit this value if there is no user set value. This detects shared
602606
// libraries without the GCS property but does not the shared-libraries to be
603607
// rebuilt for successful linking
604-
if (isReportDynamic && gcsReportValue.getValue() != GcsReportPolicy::None &&
605-
ret.getValue() == GcsReportPolicy::None)
606-
ret = GcsReportPolicy::Warning;
607-
608-
return ret;
608+
if (!reportDynamicDefined && ctx.arg.zGcsReport != GcsReportPolicy::None &&
609+
ctx.arg.zGcsReportDynamic == GcsReportPolicy::None)
610+
ctx.arg.zGcsReportDynamic = GcsReportPolicy::Warning;
609611
}
610612

611613
// Report a warning for an unknown -z option.
@@ -1587,9 +1589,10 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
15871589
ctx.arg.zForceBti = hasZOption(args, "force-bti");
15881590
ctx.arg.zForceIbt = hasZOption(args, "force-ibt");
15891591
ctx.arg.zGcs = getZGcs(ctx, args);
1590-
ctx.arg.zGcsReport = getZGcsReport(ctx, args, /* isReportDynamic */ false);
1591-
ctx.arg.zGcsReportDynamic =
1592-
getZGcsReport(ctx, args, /* isReportDynamic */ true, ctx.arg.zGcsReport);
1592+
// getZGcsReport assings the values for `ctx.arg.zGcsReport` and
1593+
// `ctx.arg.zGcsReportDynamic within the function. By doing this, it saves
1594+
// calling the function twice, as both values can be parsed at once.
1595+
getZGcsReport(ctx, args);
15931596
ctx.arg.zGlobal = hasZOption(args, "global");
15941597
ctx.arg.zGnustack = getZGnuStack(args);
15951598
ctx.arg.zHazardplt = hasZOption(args, "hazardplt");
@@ -2877,7 +2880,7 @@ static void readSecurityNotes(Ctx &ctx) {
28772880
<< ": -z bti-report: file does not have "
28782881
"GNU_PROPERTY_AARCH64_FEATURE_1_BTI property";
28792882

2880-
reportUnless(ctx.arg.zGcsReport.toString(),
2883+
reportUnless(gcsReportPolicytoString(ctx.arg.zGcsReport),
28812884
features & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)
28822885
<< f
28832886
<< ": -z gcs-report: file does not have "
@@ -2955,7 +2958,7 @@ static void readSecurityNotes(Ctx &ctx) {
29552958
// either `warning` or `error`.
29562959
if (ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)
29572960
for (SharedFile *f : ctx.sharedFiles)
2958-
reportUnless(ctx.arg.zGcsReportDynamic.toString(),
2961+
reportUnless(gcsReportPolicytoString(ctx.arg.zGcsReportDynamic),
29592962
f->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)
29602963
<< f
29612964
<< ": GCS is required by -z gcs, but this shared library lacks the "

lld/ELF/InputFiles.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -1448,13 +1448,13 @@ std::vector<uint32_t> SharedFile::parseVerneed(const ELFFile<ELFT> &obj,
14481448
template <typename ELFT>
14491449
void SharedFile::parseGnuAndFeatures(const uint8_t *base,
14501450
const typename ELFT::PhdrRange headers) {
1451-
if (numElfPhdrs == 0)
1451+
if (headers.size() == 0)
14521452
return;
14531453
uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
14541454
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
14551455
: GNU_PROPERTY_X86_FEATURE_1_AND;
14561456

1457-
for (unsigned i = 0; i < numElfPhdrs; i++) {
1457+
for (unsigned i = 0; i < headers.size(); i++) {
14581458
if (headers[i].p_type != PT_GNU_PROPERTY)
14591459
continue;
14601460
const typename ELFT::Note note(
@@ -1510,10 +1510,7 @@ template <class ELFT> void SharedFile::parse() {
15101510
ArrayRef<Elf_Dyn> dynamicTags;
15111511
const ELFFile<ELFT> obj = this->getObj<ELFT>();
15121512
ArrayRef<Elf_Shdr> sections = getELFShdrs<ELFT>();
1513-
15141513
ArrayRef<Elf_Phdr> pHeaders = CHECK2(obj.program_headers(), this);
1515-
elfPhdrs = pHeaders.data();
1516-
numElfPhdrs = pHeaders.size();
15171514

15181515
const Elf_Shdr *versymSec = nullptr;
15191516
const Elf_Shdr *verdefSec = nullptr;
@@ -1584,7 +1581,7 @@ template <class ELFT> void SharedFile::parse() {
15841581

15851582
verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec);
15861583
std::vector<uint32_t> verneeds = parseVerneed<ELFT>(obj, verneedSec);
1587-
parseGnuAndFeatures<ELFT>(obj.base(), getELFPhdrs<ELFT>());
1584+
parseGnuAndFeatures<ELFT>(obj.base(), pHeaders);
15881585

15891586
// Parse ".gnu.version" section which is a parallel array for the symbol
15901587
// table. If a given file doesn't have a ".gnu.version" section, we use

lld/ELF/InputFiles.h

-9
Original file line numberDiff line numberDiff line change
@@ -360,15 +360,6 @@ class SharedFile : public ELFFileBase {
360360
// parsed. Only filled for `--no-allow-shlib-undefined`.
361361
SmallVector<Symbol *, 0> requiredSymbols;
362362

363-
template <typename ELFT> typename ELFT::PhdrRange getELFPhdrs() const {
364-
return typename ELFT::PhdrRange(
365-
reinterpret_cast<const typename ELFT::Phdr *>(elfPhdrs), numElfPhdrs);
366-
}
367-
368-
protected:
369-
const void *elfPhdrs = nullptr;
370-
uint32_t numElfPhdrs = 0;
371-
372363
private:
373364
template <typename ELFT>
374365
std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj,

lld/docs/ReleaseNotes.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ Non-comprehensive list of changes in this release
2525

2626
ELF Improvements
2727
----------------
28-
* For AArch64, support for the `-zgcs-report-dynamic`` option has been added. This will provide users with
28+
* For AArch64, support for the ``-zgcs-report-dynamic`` option has been added. This will provide users with
2929
the ability to check any Dynamic Objects explicitly passed to LLD for the GNU GCS Attribute Flag. This is
30-
required for all files when linking with GCS enabled. Unless defined by the user, `-zgcs-report-dynamic``
31-
inherits its value from the `-zgcs-report` option, capped at the `warning` level to ensure that a users
30+
required for all files when linking with GCS enabled. Unless defined by the user, ``-zgcs-report-dynamic``
31+
inherits its value from the ``-zgcs-report`` option, capped at the ``warning`` level to ensure that a users
3232
module can still compile. This behaviour is designed to match the GNU ld Linker.
3333

3434
Breaking changes

0 commit comments

Comments
 (0)