[lld] [LLD][COFF] Add -build-id flag to genrate .buildid section. (PR #71433)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 6 11:35:22 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Zequan Wu (ZequanWu)
<details>
<summary>Changes</summary>
[RFC](https://discourse.llvm.org/t/rfc-add-build-id-flag-to-lld-link/74661)
With this change, lld-link generates `.buildid` section that contains build id hash under two cases:
1. `/buildid` flag is given.
2. `/lldmingw` and `/debug` are given and not generating PDB.
So, it will generate duplicated debug directories when `/buildid` and `/pdb:` are given, one in `.buildid` section and another one in `.rdata` section.
---
Full diff: https://github.com/llvm/llvm-project/pull/71433.diff
6 Files Affected:
- (modified) lld/COFF/Config.h (+1)
- (modified) lld/COFF/Driver.cpp (+5)
- (modified) lld/COFF/Options.td (+2)
- (modified) lld/COFF/Writer.cpp (+15-7)
- (modified) lld/MinGW/Options.td (+1-1)
- (modified) lld/test/COFF/rsds.test (+34-20)
``````````diff
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 1c338cc63fa87d2..4e4811357d26a46 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -317,6 +317,7 @@ struct Configuration {
bool writeCheckSum = false;
EmitKind emit = EmitKind::Obj;
bool allowDuplicateWeak = false;
+ bool buildID = false;
};
} // namespace lld::coff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 5613c2e6993a5af..0fa6fd6d34cf6a7 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2332,6 +2332,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
}
+ // Generate build id hash in .buildid section when:
+ // 1. /build-id
+ // 2. /lldmingw + /debug and not generating pdb file.
+ config->buildID = args.hasArg(OPT_build_id) ||
+ (config->mingw && config->debug && !shouldCreatePDB);
// Set default image base if /base is not given.
if (config->imageBase == uint64_t(-1))
config->imageBase = getDefaultImageBase();
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 977657a433dc581..cc7ce4fdbeea037 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -299,6 +299,8 @@ def : Flag<["--"], "time-trace">, Alias<time_trace_eq>,
def time_trace_granularity_eq: Joined<["--"], "time-trace-granularity=">,
HelpText<"Minimum time granularity (in microseconds) traced by time profiler">;
+def build_id: F<"build-id">, HelpText<"Generate build ID">;
+
// Flags for debugging
def lldmap : F<"lldmap">;
def lldmap_file : P_priv<"lldmap">;
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 43d8e7c1d530859..dca148a62e9d171 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1041,14 +1041,14 @@ void Writer::createMiscChunks() {
// Create Debug Information Chunks
OutputSection *debugInfoSec = config->mingw ? buildidSec : rdataSec;
- if (config->debug || config->repro || config->cetCompat) {
+ if (config->buildID || config->debug || config->repro || config->cetCompat) {
debugDirectory =
make<DebugDirectoryChunk>(ctx, debugRecords, config->repro);
debugDirectory->setAlignment(4);
debugInfoSec->addChunk(debugDirectory);
}
- if (config->debug) {
+ if (config->debug || config->buildID) {
// Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
// output a PDB no matter what, and this chunk provides the only means of
// allowing a debugger to match a PDB and an executable. So we need it even
@@ -1069,6 +1069,16 @@ void Writer::createMiscChunks() {
debugInfoSec->addChunk(r.second);
}
+ // If .buildid section was not chosen and /build-id is given, create .buildid
+ // section.
+ if (config->buildID && debugInfoSec != buildidSec) {
+ buildidSec->addChunk(debugDirectory);
+ for (std::pair<COFF::DebugType, Chunk *> r : debugRecords) {
+ r.second->setAlignment(4);
+ buildidSec->addChunk(r.second);
+ }
+ }
+
// Create SEH table. x86-only.
if (config->safeSEH)
createSEHTable();
@@ -2028,7 +2038,7 @@ void Writer::writeBuildId() {
// PE contents.
Configuration *config = &ctx.config;
- if (config->debug) {
+ if (config->debug || config->buildID) {
assert(buildId && "BuildId is not set!");
// BuildId->BuildId was filled in when the PDB was written.
}
@@ -2043,16 +2053,14 @@ void Writer::writeBuildId() {
uint32_t timestamp = config->timestamp;
uint64_t hash = 0;
- bool generateSyntheticBuildId =
- config->mingw && config->debug && config->pdbPath.empty();
- if (config->repro || generateSyntheticBuildId)
+ if (config->repro || config->buildID)
hash = xxh3_64bits(outputFileData);
if (config->repro)
timestamp = static_cast<uint32_t>(hash);
- if (generateSyntheticBuildId) {
+ if (config->buildID) {
// For MinGW builds without a PDB file, we still generate a build id
// to allow associating a crash dump to the executable.
buildId->buildId->PDB70.CVSignature = OMF::Signature::PDB70;
diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td
index fa4c4ecc75d6543..87b5c4fff68cef6 100644
--- a/lld/MinGW/Options.td
+++ b/lld/MinGW/Options.td
@@ -196,6 +196,7 @@ defm guard_longjmp : B<"guard-longjmp",
"Do not enable Control Flow Guard long jump hardening">;
defm error_limit:
EqLong<"error-limit", "Maximum number of errors to emit before stopping (0 = no limit)">;
+def build_id: F<"build-id">, HelpText<"Generate build ID">;
// Alias
def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">, Alias<Bdynamic>;
@@ -213,7 +214,6 @@ def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
// Ignored options
def: Joined<["-"], "O">;
def: F<"as-needed">;
-def: F<"build-id">;
def: F<"disable-auto-image-base">;
def: F<"enable-auto-image-base">;
def: F<"end-group">;
diff --git a/lld/test/COFF/rsds.test b/lld/test/COFF/rsds.test
index 475249ca4056669..783ac08255c031b 100644
--- a/lld/test/COFF/rsds.test
+++ b/lld/test/COFF/rsds.test
@@ -22,9 +22,23 @@
# RUN: lld-link /Brepro /debug /dll /out:%t.dll /entry:DllMain %t.obj
# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix REPRODEBUG %s
+# Generate .buildid section when /lldmingw + /debug:dwarf are given and not generating pdb file.
# RUN: rm -f %t.dll %t.pdb
# RUN: lld-link /lldmingw /debug:dwarf /dll /out:%t.dll /entry:DllMain %t.obj
-# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix MINGW %s
+# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix BUILDID %s
+
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /lldmingw /debug:dwarf /build-id /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix BUILDID %s
+
+# Generate .buildid section when /build-id is given.
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /build-id /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix BUILDID %s
+
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /build-id /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix BUILDID %s
# CHECK: File: [[FILE:.*]].dll
# CHECK: DebugDirectory [
@@ -148,25 +162,25 @@
# REPRODEBUG: }
# REPRODEBUG: ]
-# MINGW: File: {{.*}}.dll
-# MINGW: DebugDirectory [
-# MINGW: DebugEntry {
-# MINGW: Characteristics: 0x0
-# MINGW: TimeDateStamp:
-# MINGW: MajorVersion: 0x0
-# MINGW: MinorVersion: 0x0
-# MINGW: Type: CodeView (0x2)
-# MINGW: SizeOfData: 0x{{[^0]}}
-# MINGW: AddressOfRawData: 0x{{[^0]}}
-# MINGW: PointerToRawData: 0x{{[^0]}}
-# MINGW: PDBInfo {
-# MINGW: PDBSignature: 0x53445352
-# MINGW: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
-# MINGW: PDBAge: 1
-# MINGW: PDBFileName:
-# MINGW: }
-# MINGW: }
-# MINGW: ]
+# BUILDID: File: {{.*}}.dll
+# BUILDID: DebugDirectory [
+# BUILDID: DebugEntry {
+# BUILDID: Characteristics: 0x0
+# BUILDID: TimeDateStamp:
+# BUILDID: MajorVersion: 0x0
+# BUILDID: MinorVersion: 0x0
+# BUILDID: Type: CodeView (0x2)
+# BUILDID: SizeOfData: 0x{{[^0]}}
+# BUILDID: AddressOfRawData: 0x{{[^0]}}
+# BUILDID: PointerToRawData: 0x{{[^0]}}
+# BUILDID: PDBInfo {
+# BUILDID: PDBSignature: 0x53445352
+# BUILDID: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
+# BUILDID: PDBAge: 1
+# BUILDID: PDBFileName:
+# BUILDID: }
+# BUILDID: }
+# BUILDID: ]
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386
``````````
</details>
https://github.com/llvm/llvm-project/pull/71433
More information about the llvm-commits
mailing list